useFullSpanFromTrace.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import type {Entry, EntrySpans} from 'sentry/types';
  2. import {EntryType} from 'sentry/types';
  3. import type {Sort} from 'sentry/utils/discover/fields';
  4. import {useEventDetails} from 'sentry/views/starfish/queries/useEventDetails';
  5. import {useIndexedSpans} from 'sentry/views/starfish/queries/useIndexedSpans';
  6. import {SpanIndexedField} from 'sentry/views/starfish/types';
  7. const DEFAULT_SORT: Sort[] = [{field: 'timestamp', kind: 'desc'}];
  8. // NOTE: Fetching the top one is a bit naive, but works for now. A better
  9. // approach might be to fetch several at a time, and let the hook consumer
  10. // decide how to display them
  11. export function useFullSpanFromTrace(
  12. group?: string,
  13. sorts?: Sort[],
  14. enabled: boolean = true,
  15. extraFilters: Record<string, string> = {}
  16. ) {
  17. const filters = {...extraFilters};
  18. if (group) {
  19. filters[SpanIndexedField.SPAN_GROUP] = group;
  20. }
  21. // TODO: we're using all SpanIndexedFields here, but maybe we should only use what we need?
  22. // Truncate to 20 fields otherwise discover will complain.
  23. const fields = Object.values(SpanIndexedField).slice(0, 20);
  24. const indexedSpansResponse = useIndexedSpans({
  25. filters,
  26. sorts: sorts || DEFAULT_SORT,
  27. limit: 1,
  28. enabled,
  29. fields,
  30. referrer: 'api.starfish.full-span-from-trace',
  31. });
  32. const firstIndexedSpan = indexedSpansResponse.data?.[0];
  33. const eventDetailsResponse = useEventDetails({
  34. eventId: firstIndexedSpan?.[SpanIndexedField.TRANSACTION_ID],
  35. projectSlug: firstIndexedSpan?.[SpanIndexedField.PROJECT],
  36. });
  37. const spanEntry = eventDetailsResponse.data?.entries.find(
  38. (entry: Entry): entry is EntrySpans => {
  39. return entry.type === EntryType.SPANS;
  40. }
  41. );
  42. const fullSpan = spanEntry?.data?.find(
  43. span => span.span_id === firstIndexedSpan?.[SpanIndexedField.ID]
  44. );
  45. // N.B. There isn't a great pattern for us to merge the responses together,
  46. // so we're only merging the three most important properties
  47. return {
  48. isLoading: indexedSpansResponse.isLoading || eventDetailsResponse.isLoading,
  49. isFetching: indexedSpansResponse.isFetching || eventDetailsResponse.isFetching,
  50. isError: indexedSpansResponse.isError || eventDetailsResponse.isError,
  51. data: fullSpan,
  52. };
  53. }