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