useSpanSamples.tsx 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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(groupId && transactionName && !isLoadingSeries);
  49. const result = useQuery<SpanSample[]>({
  50. queryKey: [
  51. 'span-samples',
  52. groupId,
  53. transactionName,
  54. dateCondtions.statsPeriod,
  55. dateCondtions.start,
  56. dateCondtions.end,
  57. ],
  58. queryFn: async () => {
  59. const {data} = await api.requestPromise(
  60. `${url}?${qs.stringify({
  61. ...dateCondtions,
  62. ...{utc: location.query.utc},
  63. lowerBound: 0,
  64. firstBound: maxYValue * (1 / 3),
  65. secondBound: maxYValue * (2 / 3),
  66. upperBound: maxYValue,
  67. query: query.formatString(),
  68. })}`
  69. );
  70. return data
  71. ?.map((d: SpanSample) => ({
  72. ...d,
  73. timestamp: moment(d.timestamp).format(DATE_FORMAT),
  74. }))
  75. .sort((a: SpanSample, b: SpanSample) => b[SPAN_SELF_TIME] - a[SPAN_SELF_TIME]);
  76. },
  77. refetchOnWindowFocus: false,
  78. enabled,
  79. initialData: [],
  80. });
  81. return {...result, isEnabled: enabled};
  82. };