mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
132 lines
3.8 KiB
TypeScript
132 lines
3.8 KiB
TypeScript
import moment from 'moment';
|
|
import * as qs from 'query-string';
|
|
|
|
import {useQuery} from 'sentry/utils/queryClient';
|
|
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
|
|
import useApi from 'sentry/utils/useApi';
|
|
import {useLocation} from 'sentry/utils/useLocation';
|
|
import useOrganization from 'sentry/utils/useOrganization';
|
|
import usePageFilters from 'sentry/utils/usePageFilters';
|
|
import {computeAxisMax} from 'sentry/views/starfish/components/chart';
|
|
import {useSpanMetricsSeries} from 'sentry/views/starfish/queries/useSpanMetricsSeries';
|
|
import type {
|
|
SpanIndexedFieldTypes,
|
|
SpanMetricsQueryFilters,
|
|
} from 'sentry/views/starfish/types';
|
|
import {SpanIndexedField} from 'sentry/views/starfish/types';
|
|
import {getDateConditions} from 'sentry/views/starfish/utils/getDateConditions';
|
|
import {DATE_FORMAT} from 'sentry/views/starfish/utils/useSpansQuery';
|
|
|
|
const {SPAN_SELF_TIME, SPAN_GROUP} = SpanIndexedField;
|
|
|
|
type Options = {
|
|
groupId: string;
|
|
transactionName: string;
|
|
additionalFields?: string[];
|
|
query?: string[];
|
|
release?: string;
|
|
transactionMethod?: string;
|
|
};
|
|
|
|
export type SpanSample = Pick<
|
|
SpanIndexedFieldTypes,
|
|
| SpanIndexedField.SPAN_SELF_TIME
|
|
| SpanIndexedField.TRANSACTION_ID
|
|
| SpanIndexedField.PROJECT
|
|
| SpanIndexedField.TIMESTAMP
|
|
| SpanIndexedField.ID
|
|
| SpanIndexedField.PROFILE_ID
|
|
| SpanIndexedField.HTTP_RESPONSE_CONTENT_LENGTH
|
|
>;
|
|
|
|
export const useSpanSamples = (options: Options) => {
|
|
const organization = useOrganization();
|
|
const url = `/api/0/organizations/${organization.slug}/spans-samples/`;
|
|
const api = useApi();
|
|
const pageFilter = usePageFilters();
|
|
const {
|
|
groupId,
|
|
transactionName,
|
|
transactionMethod,
|
|
release,
|
|
query: extraQuery = [],
|
|
additionalFields,
|
|
} = options;
|
|
const location = useLocation();
|
|
|
|
const query = new MutableSearch([
|
|
`${SPAN_GROUP}:${groupId}`,
|
|
`transaction:"${transactionName}"`,
|
|
...extraQuery,
|
|
]);
|
|
|
|
const filters: SpanMetricsQueryFilters = {
|
|
transaction: transactionName,
|
|
};
|
|
|
|
if (transactionMethod) {
|
|
query.addFilterValue('transaction.method', transactionMethod);
|
|
filters['transaction.method'] = transactionMethod;
|
|
}
|
|
|
|
if (release) {
|
|
query.addFilterValue('release', release);
|
|
filters.release = release;
|
|
}
|
|
|
|
const dateCondtions = getDateConditions(pageFilter.selection);
|
|
|
|
const {isLoading: isLoadingSeries, data: spanMetricsSeriesData} = useSpanMetricsSeries({
|
|
filters: {'span.group': groupId, ...filters},
|
|
yAxis: [`avg(${SPAN_SELF_TIME})`],
|
|
referrer: 'api.starfish.sidebar-span-metrics',
|
|
});
|
|
|
|
const maxYValue = computeAxisMax([spanMetricsSeriesData?.[`avg(${SPAN_SELF_TIME})`]]);
|
|
|
|
const enabled = Boolean(
|
|
groupId && transactionName && !isLoadingSeries && pageFilter.isReady
|
|
);
|
|
|
|
const queryString = query.formatString();
|
|
|
|
const result = useQuery<SpanSample[]>({
|
|
queryKey: [
|
|
'span-samples',
|
|
groupId,
|
|
transactionName,
|
|
dateCondtions.statsPeriod,
|
|
dateCondtions.start,
|
|
dateCondtions.end,
|
|
queryString,
|
|
additionalFields?.join(','),
|
|
],
|
|
queryFn: async () => {
|
|
const {data} = await api.requestPromise(
|
|
`${url}?${qs.stringify({
|
|
...dateCondtions,
|
|
...{utc: location.query.utc},
|
|
lowerBound: 0,
|
|
firstBound: maxYValue * (1 / 3),
|
|
secondBound: maxYValue * (2 / 3),
|
|
upperBound: maxYValue,
|
|
project: pageFilter.selection.projects,
|
|
query: queryString,
|
|
...(additionalFields?.length ? {additionalFields} : {}),
|
|
})}`
|
|
);
|
|
return data
|
|
?.map((d: SpanSample) => ({
|
|
...d,
|
|
timestamp: moment(d.timestamp).format(DATE_FORMAT),
|
|
}))
|
|
.sort((a: SpanSample, b: SpanSample) => b[SPAN_SELF_TIME] - a[SPAN_SELF_TIME]);
|
|
},
|
|
refetchOnWindowFocus: false,
|
|
enabled,
|
|
initialData: [],
|
|
});
|
|
|
|
return {...result, isEnabled: enabled};
|
|
};
|