useSpanSamples.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import moment from 'moment';
  2. import * as qs from 'query-string';
  3. import {useQuery} from 'sentry/utils/queryClient';
  4. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  5. import useApi from 'sentry/utils/useApi';
  6. import {useLocation} from 'sentry/utils/useLocation';
  7. import useOrganization from 'sentry/utils/useOrganization';
  8. import usePageFilters from 'sentry/utils/usePageFilters';
  9. import {computeAxisMax} from 'sentry/views/starfish/components/chart';
  10. import {useSpanMetricsSeries} from 'sentry/views/starfish/queries/useSpanMetricsSeries';
  11. import {SpanIndexedField, SpanIndexedFieldTypes} from 'sentry/views/starfish/types';
  12. import {getDateConditions} from 'sentry/views/starfish/utils/getDateConditions';
  13. import {DATE_FORMAT} from 'sentry/views/starfish/utils/useSpansQuery';
  14. const {SPAN_SELF_TIME, SPAN_GROUP} = SpanIndexedField;
  15. type Options = {
  16. groupId: string;
  17. transactionName: string;
  18. transactionMethod?: string;
  19. };
  20. export type SpanSample = Pick<
  21. SpanIndexedFieldTypes,
  22. | SpanIndexedField.SPAN_SELF_TIME
  23. | SpanIndexedField.TRANSACTION_ID
  24. | SpanIndexedField.PROJECT
  25. | SpanIndexedField.TIMESTAMP
  26. | SpanIndexedField.ID
  27. >;
  28. export const useSpanSamples = (options: Options) => {
  29. const organization = useOrganization();
  30. const url = `/api/0/organizations/${organization.slug}/spans-samples/`;
  31. const api = useApi();
  32. const pageFilter = usePageFilters();
  33. const {groupId, transactionName, transactionMethod} = options;
  34. const location = useLocation();
  35. const query = new MutableSearch([
  36. `${SPAN_GROUP}:${groupId}`,
  37. `transaction:"${transactionName}"`,
  38. ]);
  39. if (transactionMethod) {
  40. query.addFilterValue('transaction.method', transactionMethod);
  41. }
  42. const filters = {
  43. transactionName,
  44. };
  45. if (transactionMethod) {
  46. filters['transaction.method'] = transactionMethod;
  47. }
  48. const dateCondtions = getDateConditions(pageFilter.selection);
  49. const {isLoading: isLoadingSeries, data: spanMetricsSeriesData} = useSpanMetricsSeries(
  50. groupId,
  51. filters,
  52. [`avg(${SPAN_SELF_TIME})`],
  53. 'api.starfish.sidebar-span-metrics'
  54. );
  55. const maxYValue = computeAxisMax([spanMetricsSeriesData?.[`avg(${SPAN_SELF_TIME})`]]);
  56. const enabled = Boolean(
  57. groupId && transactionName && !isLoadingSeries && pageFilter.isReady
  58. );
  59. const result = useQuery<SpanSample[]>({
  60. queryKey: [
  61. 'span-samples',
  62. groupId,
  63. transactionName,
  64. dateCondtions.statsPeriod,
  65. dateCondtions.start,
  66. dateCondtions.end,
  67. ],
  68. queryFn: async () => {
  69. const {data} = await api.requestPromise(
  70. `${url}?${qs.stringify({
  71. ...dateCondtions,
  72. ...{utc: location.query.utc},
  73. lowerBound: 0,
  74. firstBound: maxYValue * (1 / 3),
  75. secondBound: maxYValue * (2 / 3),
  76. upperBound: maxYValue,
  77. project: pageFilter.selection.projects,
  78. query: query.formatString(),
  79. })}`
  80. );
  81. return data
  82. ?.map((d: SpanSample) => ({
  83. ...d,
  84. timestamp: moment(d.timestamp).format(DATE_FORMAT),
  85. }))
  86. .sort((a: SpanSample, b: SpanSample) => b[SPAN_SELF_TIME] - a[SPAN_SELF_TIME]);
  87. },
  88. refetchOnWindowFocus: false,
  89. enabled,
  90. initialData: [],
  91. });
  92. return {...result, isEnabled: enabled};
  93. };