useReplayTraceMeta.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import {useMemo} from 'react';
  2. import type {Location} from 'history';
  3. import {getTimeStampFromTableDateField, getUtcDateString} from 'sentry/utils/dates';
  4. import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
  5. import EventView from 'sentry/utils/discover/eventView';
  6. import {useApiQuery} from 'sentry/utils/queryClient';
  7. import useOrganization from 'sentry/utils/useOrganization';
  8. import type {ReplayTrace} from 'sentry/views/replays/detail/trace/useReplayTraces';
  9. import type {ReplayRecord} from 'sentry/views/replays/types';
  10. import {type TraceMetaQueryResults, useTraceMeta} from './useTraceMeta';
  11. // Fetches the meta data for all the traces in a replay and combines the results.
  12. export function useReplayTraceMeta(
  13. replayRecord: ReplayRecord | undefined
  14. ): TraceMetaQueryResults {
  15. const organization = useOrganization();
  16. // EventView that is used to fetch the list of events for the replay
  17. const eventView = useMemo(() => {
  18. if (!replayRecord) {
  19. return null;
  20. }
  21. const replayId = replayRecord?.id;
  22. const projectId = replayRecord?.project_id;
  23. const start = getUtcDateString(replayRecord?.started_at.getTime());
  24. const end = getUtcDateString(replayRecord?.finished_at.getTime());
  25. return EventView.fromSavedQuery({
  26. id: undefined,
  27. name: `Traces in replay ${replayId}`,
  28. fields: ['trace', 'count(trace)', 'min(timestamp)'],
  29. orderby: 'min_timestamp',
  30. query: `replayId:${replayId}`,
  31. projects: [Number(projectId)],
  32. version: 2,
  33. start,
  34. end,
  35. });
  36. }, [replayRecord]);
  37. const start = getUtcDateString(replayRecord?.started_at.getTime());
  38. const end = getUtcDateString(replayRecord?.finished_at.getTime());
  39. const {data: eventsData, isPending: eventsIsLoading} = useApiQuery<{
  40. data: TableDataRow[];
  41. }>(
  42. [
  43. `/organizations/${organization.slug}/events/`,
  44. {
  45. query: eventView
  46. ? {
  47. ...eventView.getEventsAPIPayload({
  48. start,
  49. end,
  50. limit: 10,
  51. } as unknown as Location),
  52. sort: ['min_timestamp', 'trace'],
  53. }
  54. : {},
  55. },
  56. ],
  57. {
  58. staleTime: Infinity,
  59. enabled: !!eventView && !!replayRecord,
  60. }
  61. );
  62. const replayTraces = useMemo(() => {
  63. const traces: ReplayTrace[] = [];
  64. for (const row of eventsData?.data ?? []) {
  65. if (row.trace) {
  66. traces.push({
  67. traceSlug: String(row.trace),
  68. timestamp: getTimeStampFromTableDateField(row['min(timestamp)']),
  69. });
  70. }
  71. }
  72. return traces;
  73. }, [eventsData]);
  74. const meta = useTraceMeta(replayTraces);
  75. const metaResults = useMemo(() => {
  76. return {
  77. data: meta.data,
  78. isLoading: eventsIsLoading || meta.status === 'pending',
  79. errors: meta.errors,
  80. status: meta.status,
  81. };
  82. }, [meta, eventsIsLoading]);
  83. return metaResults;
  84. }