useSpanSamples.tsx 3.5 KB

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