useSpanSamples.tsx 2.8 KB

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