Browse Source

feat(traces): Add definitions for span field search keys (#74787)

Adds definitions for span search fields. This affects mainly the search
in the Traces page, but also several searchbars in Insights modules that
allow for searching on spans.

Initially, I planned on referencing `SpanIndexedField` and
`SpanMetricsField` when setting the definitions, but importing it
results in a circular dependency due to the file they reside in also
importing from `static/app/utils/fields/index.ts`. I decided to create a
`TraceFields` enum instead which results in some code duplication, but
the alternative is a massive and fairly messy refactor.

Related to https://github.com/getsentry/sentry/issues/74276


![image](https://github.com/user-attachments/assets/969debf3-6d39-42ce-b457-724b12932f29)


Side note; I noticed that most of these definitions are missing in our
documentation, we should update them there as well once we've decided on
adequate descriptions for these fields.
Ash 7 months ago
parent
commit
a1ec779967

+ 1 - 1
static/app/utils/discover/fields.tsx

@@ -11,7 +11,7 @@ import {
   SESSIONS_OPERATIONS,
 } from 'sentry/views/dashboards/widgetBuilder/releaseWidget/fields';
 import {STARFISH_FIELDS} from 'sentry/views/insights/common/utils/constants';
-import {STARFISH_AGGREGATION_FIELDS} from 'sentry/views/insights/types';
+import {STARFISH_AGGREGATION_FIELDS} from 'sentry/views/insights/constants';
 
 import {
   AGGREGATION_FIELDS,

+ 84 - 0
static/app/utils/fields/index.ts

@@ -1,5 +1,6 @@
 import {t} from 'sentry/locale';
 import type {TagCollection} from 'sentry/types/group';
+import {SpanIndexedField} from 'sentry/views/insights/types';
 
 // Don't forget to update https://docs.sentry.io/product/sentry-basics/search/searchable-properties/ for any changes made here
 
@@ -530,16 +531,99 @@ export const SPAN_OP_FIELDS: Record<SpanOpBreakdown, FieldDefinition> = {
   },
 };
 
+type TraceFields =
+  | SpanIndexedField.SPAN_ACTION
+  | SpanIndexedField.SPAN_CATEGORY
+  | SpanIndexedField.SPAN_DESCRIPTION
+  | SpanIndexedField.SPAN_DOMAIN
+  | SpanIndexedField.SPAN_DURATION
+  | SpanIndexedField.SPAN_GROUP
+  | SpanIndexedField.SPAN_MODULE
+  | SpanIndexedField.SPAN_OP
+  // TODO: Remove self time field when it is deprecated
+  | SpanIndexedField.SPAN_SELF_TIME
+  | SpanIndexedField.SPAN_STATUS
+  | SpanIndexedField.RESPONSE_CODE;
+
+const TRACE_FIELD_DEFINITIONS: Record<TraceFields, FieldDefinition> = {
+  /** Indexed Fields */
+  [SpanIndexedField.SPAN_ACTION]: {
+    desc: t(
+      'The type of span action, e.g `SELECT` for a SQL span or `POST` for an HTTP span'
+    ),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.SPAN_CATEGORY]: {
+    desc: t(
+      'The Insights module that the span is associated with, e.g `cache`, `db`, `http`, etc.'
+    ),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.SPAN_DESCRIPTION]: {
+    desc: t('Parameterized and scrubbed description of the span'),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.SPAN_DOMAIN]: {
+    desc: t(
+      'General scope of the span’s action, i.e. the tables involved in a `db` span or the host name in an `http` span'
+    ),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.SPAN_DURATION]: {
+    desc: t('The total time taken by the span'),
+    kind: FieldKind.METRICS,
+    valueType: FieldValueType.DURATION,
+  },
+  [SpanIndexedField.SPAN_GROUP]: {
+    desc: t('Unique hash of the span’s description'),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.SPAN_MODULE]: {
+    desc: t(
+      'The Insights module that the span is associated with, e.g `cache`, `db`, `http`, etc.'
+    ),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.SPAN_OP]: {
+    desc: t('The operation of the span, e.g `http.client`, `middleware`'),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.SPAN_SELF_TIME]: {
+    desc: t('The duration of the span excluding the duration of its child spans'),
+    kind: FieldKind.METRICS,
+    valueType: FieldValueType.DURATION,
+  },
+  [SpanIndexedField.SPAN_STATUS]: {
+    desc: t('Status of the operation the span represents'),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+  [SpanIndexedField.RESPONSE_CODE]: {
+    desc: t('The HTTP response status code'),
+    kind: FieldKind.FIELD,
+    valueType: FieldValueType.STRING,
+  },
+};
+
 type AllEventFieldKeys =
   | keyof typeof AGGREGATION_FIELDS
   | keyof typeof MEASUREMENT_FIELDS
   | keyof typeof SPAN_OP_FIELDS
+  | keyof typeof TRACE_FIELD_DEFINITIONS
   | FieldKey;
 
 const EVENT_FIELD_DEFINITIONS: Record<AllEventFieldKeys, FieldDefinition> = {
   ...AGGREGATION_FIELDS,
   ...MEASUREMENT_FIELDS,
   ...SPAN_OP_FIELDS,
+  ...TRACE_FIELD_DEFINITIONS,
   [FieldKey.AGE]: {
     desc: t('The age of the issue in relative time'),
     kind: FieldKind.FIELD,

+ 64 - 0
static/app/views/insights/constants.tsx

@@ -0,0 +1,64 @@
+import {t} from 'sentry/locale';
+import type {AggregationOutputType} from 'sentry/utils/discover/fields';
+import {type FieldDefinition, FieldKind, FieldValueType} from 'sentry/utils/fields';
+import {SpanFunction} from 'sentry/views/insights/types';
+
+export const STARFISH_AGGREGATION_FIELDS: Record<
+  SpanFunction,
+  FieldDefinition & {defaultOutputType: AggregationOutputType}
+> = {
+  [SpanFunction.SPS]: {
+    desc: t('Spans per second'),
+    kind: FieldKind.FUNCTION,
+    defaultOutputType: 'number',
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.SPM]: {
+    desc: t('Spans per minute'),
+    kind: FieldKind.FUNCTION,
+    defaultOutputType: 'number',
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.TIME_SPENT_PERCENTAGE]: {
+    desc: t('Span time spent percentage'),
+    defaultOutputType: 'percentage',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.HTTP_ERROR_COUNT]: {
+    desc: t('Count of 5XX http errors'),
+    defaultOutputType: 'integer',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.HTTP_RESPONSE_RATE]: {
+    desc: t('Percentage of HTTP responses by code'),
+    defaultOutputType: 'percentage',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.CACHE_HIT_RATE]: {
+    desc: t('Percentage of cache hits'),
+    defaultOutputType: 'percentage',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.CACHE_MISS_RATE]: {
+    desc: t('Percentage of cache misses'),
+    defaultOutputType: 'percentage',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.COUNT_OP]: {
+    desc: t('Count of spans with matching operation'),
+    defaultOutputType: 'integer',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
+  [SpanFunction.TRACE_STATUS_RATE]: {
+    desc: t('Percentage of spans with matching trace status'),
+    defaultOutputType: 'percentage',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
+};

+ 0 - 71
static/app/views/insights/types.tsx

@@ -1,9 +1,3 @@
-import {t} from 'sentry/locale';
-import type {AggregationOutputType} from 'sentry/utils/discover/fields';
-import {DiscoverDatasets} from 'sentry/utils/discover/types';
-import type {FieldDefinition} from 'sentry/utils/fields';
-import {FieldKind, FieldValueType} from 'sentry/utils/fields';
-
 export enum StarfishType {
   BACKEND = 'backend',
   MOBILE = 'mobile',
@@ -302,71 +296,6 @@ export enum SpanFunction {
   TRACE_STATUS_RATE = 'trace_status_rate',
 }
 
-export const StarfishDatasetFields = {
-  [DiscoverDatasets.SPANS_METRICS]: SpanIndexedField,
-  [DiscoverDatasets.SPANS_INDEXED]: SpanIndexedField,
-};
-
-export const STARFISH_AGGREGATION_FIELDS: Record<
-  SpanFunction,
-  FieldDefinition & {defaultOutputType: AggregationOutputType}
-> = {
-  [SpanFunction.SPS]: {
-    desc: t('Spans per second'),
-    kind: FieldKind.FUNCTION,
-    defaultOutputType: 'number',
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.SPM]: {
-    desc: t('Spans per minute'),
-    kind: FieldKind.FUNCTION,
-    defaultOutputType: 'number',
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.TIME_SPENT_PERCENTAGE]: {
-    desc: t('Span time spent percentage'),
-    defaultOutputType: 'percentage',
-    kind: FieldKind.FUNCTION,
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.HTTP_ERROR_COUNT]: {
-    desc: t('Count of 5XX http errors'),
-    defaultOutputType: 'integer',
-    kind: FieldKind.FUNCTION,
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.HTTP_RESPONSE_RATE]: {
-    desc: t('Percentage of HTTP responses by code'),
-    defaultOutputType: 'percentage',
-    kind: FieldKind.FUNCTION,
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.CACHE_HIT_RATE]: {
-    desc: t('Percentage of cache hits'),
-    defaultOutputType: 'percentage',
-    kind: FieldKind.FUNCTION,
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.CACHE_MISS_RATE]: {
-    desc: t('Percentage of cache misses'),
-    defaultOutputType: 'percentage',
-    kind: FieldKind.FUNCTION,
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.COUNT_OP]: {
-    desc: t('Count of spans with matching operation'),
-    defaultOutputType: 'integer',
-    kind: FieldKind.FUNCTION,
-    valueType: FieldValueType.NUMBER,
-  },
-  [SpanFunction.TRACE_STATUS_RATE]: {
-    desc: t('Percentage of spans with matching trace status'),
-    defaultOutputType: 'percentage',
-    kind: FieldKind.FUNCTION,
-    valueType: FieldValueType.NUMBER,
-  },
-};
-
 // TODO - add more functions and fields, combine shared ones, etc
 
 export const METRICS_FUNCTIONS = ['count'] as const;