useSpanFieldSupportedTags.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import {getHasTag} from 'sentry/components/events/searchBar';
  2. import type {PageFilters, TagCollection} from 'sentry/types';
  3. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  4. import {type ApiQueryKey, useApiQuery} from 'sentry/utils/queryClient';
  5. import useOrganization from 'sentry/utils/useOrganization';
  6. import usePageFilters from 'sentry/utils/usePageFilters';
  7. import {SpanIndexedField, SpanMetricsField} from 'sentry/views/insights/types';
  8. const DATASET_TO_FIELDS = {
  9. [DiscoverDatasets.SPANS_INDEXED]: SpanIndexedField,
  10. [DiscoverDatasets.SPANS_METRICS]: SpanMetricsField,
  11. };
  12. const getSpanFieldSupportedTags = (
  13. excludedTags,
  14. dataset: DiscoverDatasets.SPANS_INDEXED | DiscoverDatasets.SPANS_METRICS
  15. ) => {
  16. const fields = DATASET_TO_FIELDS[dataset];
  17. const tags: TagCollection = Object.fromEntries(
  18. Object.values(fields)
  19. .filter(v => !excludedTags.includes(v))
  20. .map(v => [v, {key: v, name: v}])
  21. );
  22. tags.has = getHasTag(tags);
  23. return tags;
  24. };
  25. interface SpanFieldEntry {
  26. key: string;
  27. name: string;
  28. }
  29. type SpanFieldsResponse = SpanFieldEntry[];
  30. const getDynamicSpanFieldsEndpoint = (
  31. orgSlug: string,
  32. projects: PageFilters['projects'],
  33. environments: PageFilters['environments']
  34. ): ApiQueryKey => [
  35. `/organizations/${orgSlug}/spans/fields/`,
  36. {
  37. query: {
  38. project: projects,
  39. environment: environments,
  40. statsPeriod: '1h', // Hard coded stats period to load recent tags fast
  41. },
  42. },
  43. ];
  44. export function useSpanMetricsFieldSupportedTags(options?: {excludedTags?: string[]}) {
  45. const {excludedTags = []} = options || {};
  46. // we do not yet support span field search by SPAN_AI_PIPELINE_GROUP
  47. return getSpanFieldSupportedTags(
  48. [SpanIndexedField.SPAN_AI_PIPELINE_GROUP, ...excludedTags],
  49. DiscoverDatasets.SPANS_METRICS
  50. );
  51. }
  52. export function useSpanFieldSupportedTags(options?: {
  53. excludedTags?: string[];
  54. projects?: PageFilters['projects'];
  55. }): TagCollection {
  56. const {excludedTags = [], projects} = options || {};
  57. const {selection} = usePageFilters();
  58. const organization = useOrganization();
  59. // we do not yet support span field search by SPAN_AI_PIPELINE_GROUP
  60. const staticTags = getSpanFieldSupportedTags(
  61. [SpanIndexedField.SPAN_AI_PIPELINE_GROUP, ...excludedTags],
  62. DiscoverDatasets.SPANS_INDEXED
  63. );
  64. const dynamicTagQuery = useApiQuery<SpanFieldsResponse>(
  65. getDynamicSpanFieldsEndpoint(
  66. organization.slug,
  67. projects ?? selection.projects,
  68. selection.environments
  69. ),
  70. {
  71. staleTime: 0,
  72. retry: false,
  73. }
  74. );
  75. if (dynamicTagQuery.isSuccess) {
  76. const dynamicTags: TagCollection = Object.fromEntries(
  77. dynamicTagQuery.data.map(entry => [entry.key, entry])
  78. );
  79. return {
  80. ...dynamicTags,
  81. ...staticTags,
  82. };
  83. }
  84. return staticTags;
  85. }