Files
2024-02-15 17:01:50 +00:00

183 lines
4.8 KiB
TypeScript

import max from 'lodash/max';
import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
import type EventView from 'sentry/utils/discover/eventView';
import type {QueryFieldValue} from 'sentry/utils/discover/fields';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
import useOrganization from 'sentry/utils/useOrganization';
import type {DataRow} from 'sentry/views/starfish/components/samplesTable/transactionSamplesTable';
const LIMIT_PER_POPULATION = 2;
/**
* This hook will fetch transaction events from 3 different types of populations and combine them in one set, then return them:
*
* - Slowest Events
* - Median / Baseline Events
* - Fastest Events
*
* It assumes that you are passing an eventView object with a query scoped to a specific transaction
*
* @param eventView An eventView containing query information, such as the transaction and other filters
*/
export default function useSlowMedianFastSamplesQuery(
eventView: EventView,
graphMax?: number
) {
const location = useLocation();
const organization = useOrganization();
const commonColumns: QueryFieldValue[] = [
{
field: 'transaction.duration',
kind: 'field',
},
{
field: 'profile_id',
kind: 'field',
},
{
field: 'timestamp',
kind: 'field',
},
{
field: 'spans.browser',
kind: 'field',
},
{
field: 'spans.db',
kind: 'field',
},
{
field: 'spans.http',
kind: 'field',
},
{
field: 'spans.resource',
kind: 'field',
},
{
field: 'spans.ui',
kind: 'field',
},
];
const eventViewAggregates = eventView
.clone()
.withColumns([
{kind: 'function', function: ['avg', 'transaction.duration', undefined, undefined]},
]);
const {isLoading: isLoadingAgg, data: aggregatesData} = useDiscoverQuery({
eventView: eventViewAggregates,
referrer: 'starfish-transaction-summary-sample-events',
location,
orgSlug: organization.slug,
options: {
refetchOnWindowFocus: false,
enabled: graphMax !== undefined,
},
});
const avg = aggregatesData
? aggregatesData.data[0]['avg(transaction.duration)']
: undefined;
const upperThird = graphMax ? max([graphMax * (2 / 3), avg]) : undefined;
const lowerThird = graphMax ? graphMax * (1 / 3) : undefined;
const slowestSamplesEventView = eventView
.clone()
.withColumns(commonColumns)
.withSorts([
{
field: 'id',
kind: 'desc',
},
]);
slowestSamplesEventView.additionalConditions = new MutableSearch(
`transaction.duration:<${graphMax} transaction.duration:>${upperThird}`
);
const {isLoading: isLoadingSlowest, data: slowestSamplesData} = useDiscoverQuery({
eventView: slowestSamplesEventView,
referrer: 'starfish-transaction-summary-sample-events',
location,
orgSlug: organization.slug,
limit: LIMIT_PER_POPULATION,
options: {
refetchOnWindowFocus: false,
enabled: graphMax !== undefined && avg !== undefined,
},
});
const medianSamplesEventView = eventView
.clone()
.withColumns(commonColumns)
.withSorts([
{
field: 'transaction.duration',
kind: 'desc',
},
]);
medianSamplesEventView.additionalConditions = new MutableSearch(
`transaction.duration:<=${upperThird} transaction.duration:>${lowerThird}`
);
const {isLoading: isLoadingMedian, data: medianSamplesData} = useDiscoverQuery({
eventView: medianSamplesEventView,
referrer: 'starfish-transaction-summary-sample-events',
location,
orgSlug: organization.slug,
limit: LIMIT_PER_POPULATION,
options: {
refetchOnWindowFocus: false,
enabled: graphMax !== undefined && avg !== undefined,
},
});
const fastestSamplesEventView = eventView
.clone()
.withColumns(commonColumns)
.withSorts([
{
field: 'transaction.duration',
kind: 'asc',
},
]);
fastestSamplesEventView.additionalConditions = new MutableSearch(
`transaction.duration:<=${lowerThird}`
);
const {isLoading: isLoadingFastest, data: fastestSamplesData} = useDiscoverQuery({
eventView: fastestSamplesEventView,
referrer: 'starfish-transaction-summary-sample-events',
location,
orgSlug: organization.slug,
limit: LIMIT_PER_POPULATION,
options: {
refetchOnWindowFocus: false,
enabled: graphMax !== undefined,
},
});
if (isLoadingAgg || isLoadingSlowest || isLoadingMedian || isLoadingFastest) {
return {isLoading: true, data: []};
}
const combinedData = [
...(slowestSamplesData?.data ?? []),
...(medianSamplesData?.data ?? []),
...(fastestSamplesData?.data ?? []),
];
return {
isLoading: false,
data: combinedData as DataRow[],
aggregatesData: aggregatesData?.data[0] ?? [],
};
}