useSpanSamples.tsx 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 {SpanIndexedFields, 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} = SpanIndexedFields;
  15. type Options = {
  16. groupId: string;
  17. transactionMethod: string;
  18. transactionName: string;
  19. };
  20. export type SpanSample = Pick<
  21. SpanIndexedFieldTypes,
  22. | SpanIndexedFields.SPAN_SELF_TIME
  23. | SpanIndexedFields.TRANSACTION_ID
  24. | SpanIndexedFields.PROJECT
  25. | SpanIndexedFields.TIMESTAMP
  26. | SpanIndexedFields.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. `transaction.method:${transactionMethod}`,
  39. ]);
  40. const dateCondtions = getDateConditions(pageFilter.selection);
  41. const {isLoading: isLoadingSeries, data: spanMetricsSeriesData} = useSpanMetricsSeries(
  42. groupId,
  43. {transactionName, 'transaction.method': transactionMethod},
  44. [`p95(${SPAN_SELF_TIME})`],
  45. 'api.starfish.sidebar-span-metrics'
  46. );
  47. const maxYValue = computeAxisMax([spanMetricsSeriesData?.[`p95(${SPAN_SELF_TIME})`]]);
  48. const enabled = Boolean(
  49. groupId && transactionName && !isLoadingSeries && pageFilter.isReady
  50. );
  51. const result = useQuery<SpanSample[]>({
  52. queryKey: [
  53. 'span-samples',
  54. groupId,
  55. transactionName,
  56. dateCondtions.statsPeriod,
  57. dateCondtions.start,
  58. dateCondtions.end,
  59. ],
  60. queryFn: async () => {
  61. const {data} = await api.requestPromise(
  62. `${url}?${qs.stringify({
  63. ...dateCondtions,
  64. ...{utc: location.query.utc},
  65. lowerBound: 0,
  66. firstBound: maxYValue * (1 / 3),
  67. secondBound: maxYValue * (2 / 3),
  68. upperBound: maxYValue,
  69. project: pageFilter.selection.projects,
  70. query: query.formatString(),
  71. })}`
  72. );
  73. return data
  74. ?.map((d: SpanSample) => ({
  75. ...d,
  76. timestamp: moment(d.timestamp).format(DATE_FORMAT),
  77. }))
  78. .sort((a: SpanSample, b: SpanSample) => b[SPAN_SELF_TIME] - a[SPAN_SELF_TIME]);
  79. },
  80. refetchOnWindowFocus: false,
  81. enabled,
  82. initialData: [],
  83. });
  84. return {...result, isEnabled: enabled};
  85. };