123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- 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',
- FRONTEND = 'frontend',
- }
- export enum ModuleName {
- HTTP = 'http',
- DB = 'db',
- CACHE = 'cache',
- VITAL = 'vital',
- QUEUE = 'queue',
- SCREEN_LOAD = 'screen_load',
- APP_START = 'app_start',
- RESOURCE = 'resource',
- AI = 'ai',
- MOBILE_UI = 'mobile-ui',
- ALL = '',
- OTHER = 'other',
- }
- export enum SpanMetricsField {
- SPAN_OP = 'span.op',
- SPAN_DESCRIPTION = 'span.description',
- SPAN_MODULE = 'span.module',
- SPAN_ACTION = 'span.action',
- SPAN_DOMAIN = 'span.domain',
- SPAN_GROUP = 'span.group',
- SPAN_DURATION = 'span.duration',
- SPAN_SELF_TIME = 'span.self_time',
- PROJECT = 'project',
- PROJECT_ID = 'project.id',
- TRANSACTION = 'transaction',
- RESOURCE_RENDER_BLOCKING_STATUS = 'resource.render_blocking_status',
- HTTP_RESPONSE_CONTENT_LENGTH = 'http.response_content_length',
- HTTP_DECODED_RESPONSE_CONTENT_LENGTH = 'http.decoded_response_content_length',
- HTTP_RESPONSE_TRANSFER_SIZE = 'http.response_transfer_size',
- FILE_EXTENSION = 'file_extension',
- AI_TOTAL_TOKENS_USED = 'ai.total_tokens.used',
- AI_TOTAL_COST = 'ai.total_cost',
- OS_NAME = 'os.name',
- APP_START_TYPE = 'app_start_type',
- DEVICE_CLASS = 'device.class',
- CACHE_HIT = 'cache.hit',
- CACHE_ITEM_SIZE = 'cache.item_size',
- MESSAGING_MESSAGE_RECEIVE_LATENCY = 'messaging.message.receive.latency',
- }
- export type SpanNumberFields =
- | SpanMetricsField.AI_TOTAL_COST
- | SpanMetricsField.AI_TOTAL_TOKENS_USED
- | SpanMetricsField.SPAN_SELF_TIME
- | SpanMetricsField.SPAN_DURATION
- | SpanMetricsField.HTTP_DECODED_RESPONSE_CONTENT_LENGTH
- | SpanMetricsField.HTTP_RESPONSE_CONTENT_LENGTH
- | SpanMetricsField.HTTP_RESPONSE_TRANSFER_SIZE
- | SpanMetricsField.MESSAGING_MESSAGE_RECEIVE_LATENCY
- | SpanMetricsField.CACHE_ITEM_SIZE;
- export type SpanStringFields =
- | 'span.op'
- | 'span.description'
- | 'span.module'
- | 'span.action'
- | 'span.group'
- | 'span.category'
- | 'transaction'
- | 'transaction.method'
- | 'release'
- | 'os.name'
- | 'span.status_code'
- | 'span.ai.pipeline.group'
- | 'project'
- | 'messaging.destination.name';
- export type SpanMetricsQueryFilters = {
- [Field in SpanStringFields]?: string;
- } & {
- [SpanMetricsField.PROJECT_ID]?: string;
- [SpanMetricsField.SPAN_DOMAIN]?: string;
- };
- export type SpanIndexedQueryFilters = {
- [Field in SpanStringFields]?: string;
- } & {
- [SpanIndexedField.PROJECT_ID]?: string;
- };
- export type SpanStringArrayFields = 'span.domain';
- export const COUNTER_AGGREGATES = ['sum', 'avg', 'min', 'max', 'p100'] as const;
- export const DISTRIBUTION_AGGREGATES = ['p50', 'p75', 'p95', 'p99'] as const;
- export const AGGREGATES = [...COUNTER_AGGREGATES, ...DISTRIBUTION_AGGREGATES] as const;
- export type Aggregate = (typeof AGGREGATES)[number];
- export type ConditionalAggregate =
- | `avg_if`
- | `count_op`
- | 'trace_status_rate'
- | 'time_spent_percentage';
- export const SPAN_FUNCTIONS = [
- 'sps',
- 'spm',
- 'count',
- 'time_spent_percentage',
- 'http_response_rate',
- 'http_error_count',
- 'cache_hit_rate',
- 'cache_miss_rate',
- 'sum',
- ] as const;
- const BREAKPOINT_CONDITIONS = ['less', 'greater'] as const;
- type BreakpointCondition = (typeof BREAKPOINT_CONDITIONS)[number];
- type RegressionFunctions = [
- `regression_score(${string},${string})`,
- `avg_by_timestamp(${string},${BreakpointCondition},${string})`,
- `epm_by_timestamp(${BreakpointCondition},${string})`,
- ][number];
- type SpanAnyFunction = `any(${string})`;
- export type SpanFunctions = (typeof SPAN_FUNCTIONS)[number];
- export type SpanMetricsResponse = {
- [Property in SpanNumberFields as `${Aggregate}(${Property})`]: number;
- } & {
- [Property in SpanFunctions as `${Property}()`]: number;
- } & {
- [Property in SpanStringFields as `${Property}`]: string;
- } & {
- [Property in SpanStringArrayFields as `${Property}`]: string[];
- } & {
- // TODO: This should include all valid HTTP codes or just all integers
- 'http_response_rate(2)': number;
- 'http_response_rate(3)': number;
- 'http_response_rate(4)': number;
- 'http_response_rate(5)': number;
- } & {
- ['project']: string;
- ['project.id']: number;
- } & {
- [Function in RegressionFunctions]: number;
- } & {
- [Function in SpanAnyFunction]: string;
- } & {
- [Property in ConditionalAggregate as
- | `${Property}(${string})`
- | `${Property}(${string},${string})`
- | `${Property}(${string},${string},${string})`]: number;
- };
- export type MetricsFilters = {
- [Property in SpanStringFields as `${Property}`]?: string | string[];
- };
- export type SpanMetricsProperty = keyof SpanMetricsResponse;
- export enum SpanIndexedField {
- ENVIRONMENT = 'environment',
- RESOURCE_RENDER_BLOCKING_STATUS = 'resource.render_blocking_status',
- HTTP_RESPONSE_CONTENT_LENGTH = 'http.response_content_length',
- SPAN_CATEGORY = 'span.category',
- SPAN_DURATION = 'span.duration',
- SPAN_SELF_TIME = 'span.self_time',
- SPAN_GROUP = 'span.group', // Span group computed from the normalized description. Matches the group in the metrics data set
- SPAN_MODULE = 'span.module',
- SPAN_DESCRIPTION = 'span.description',
- SPAN_STATUS = 'span.status',
- SPAN_OP = 'span.op',
- ID = 'span_id',
- SPAN_ACTION = 'span.action',
- SPAN_AI_PIPELINE_GROUP = 'span.ai.pipeline.group',
- SDK_NAME = 'sdk.name',
- TRACE = 'trace',
- TRANSACTION_ID = 'transaction.id',
- TRANSACTION_METHOD = 'transaction.method',
- TRANSACTION_OP = 'transaction.op',
- SPAN_DOMAIN = 'span.domain',
- TIMESTAMP = 'timestamp',
- RAW_DOMAIN = 'raw_domain',
- PROJECT = 'project',
- PROJECT_ID = 'project_id',
- PROFILE_ID = 'profile_id',
- RELEASE = 'release',
- TRANSACTION = 'transaction',
- ORIGIN_TRANSACTION = 'origin.transaction',
- REPLAY_ID = 'replay.id',
- BROWSER_NAME = 'browser.name',
- USER = 'user',
- USER_ID = 'user.id',
- USER_EMAIL = 'user.email',
- USER_USERNAME = 'user.username',
- INP = 'measurements.inp',
- INP_SCORE = 'measurements.score.inp',
- INP_SCORE_WEIGHT = 'measurements.score.weight.inp',
- TOTAL_SCORE = 'measurements.score.total',
- RESPONSE_CODE = 'span.status_code',
- CACHE_HIT = 'cache.hit',
- CACHE_ITEM_SIZE = 'measurements.cache.item_size',
- TRACE_STATUS = 'trace.status',
- MESSAGING_MESSAGE_ID = 'messaging.message.id',
- MESSAGING_MESSAGE_BODY_SIZE = 'measurements.messaging.message.body.size',
- MESSAGING_MESSAGE_RECEIVE_LATENCY = 'measurements.messaging.message.receive.latency',
- MESSAGING_MESSAGE_RETRY_COUNT = 'measurements.messaging.message.retry.count',
- MESSAGING_MESSAGE_DESTINATION_NAME = 'messaging.destination.name',
- }
- export type SpanIndexedResponse = {
- [SpanIndexedField.ENVIRONMENT]: string;
- [SpanIndexedField.RELEASE]: string;
- [SpanIndexedField.SDK_NAME]: string;
- [SpanIndexedField.SPAN_CATEGORY]: string;
- [SpanIndexedField.SPAN_DURATION]: number;
- [SpanIndexedField.SPAN_SELF_TIME]: number;
- [SpanIndexedField.SPAN_GROUP]: string;
- [SpanIndexedField.SPAN_MODULE]: string;
- [SpanIndexedField.SPAN_DESCRIPTION]: string;
- [SpanIndexedField.SPAN_OP]: string;
- [SpanIndexedField.SPAN_AI_PIPELINE_GROUP]: string;
- [SpanIndexedField.SPAN_STATUS]:
- | 'ok'
- | 'cancelled'
- | 'unknown'
- | 'invalid_argument'
- | 'deadline_exceeded'
- | 'not_found'
- | 'already_exists'
- | 'permission_denied'
- | 'resource_exhausted'
- | 'failed_precondition'
- | 'aborted'
- | 'out_of_range'
- | 'unimplemented'
- | 'internal_error'
- | 'unavailable'
- | 'data_loss'
- | 'unauthenticated';
- [SpanIndexedField.ID]: string;
- [SpanIndexedField.SPAN_ACTION]: string;
- [SpanIndexedField.TRACE]: string;
- [SpanIndexedField.TRANSACTION]: string;
- [SpanIndexedField.TRANSACTION_ID]: string;
- [SpanIndexedField.TRANSACTION_METHOD]: string;
- [SpanIndexedField.TRANSACTION_OP]: string;
- [SpanIndexedField.SPAN_DOMAIN]: string[];
- [SpanIndexedField.RAW_DOMAIN]: string;
- [SpanIndexedField.TIMESTAMP]: string;
- [SpanIndexedField.PROJECT]: string;
- [SpanIndexedField.PROJECT_ID]: number;
- [SpanIndexedField.PROFILE_ID]: string;
- [SpanIndexedField.RESOURCE_RENDER_BLOCKING_STATUS]: '' | 'non-blocking' | 'blocking';
- [SpanIndexedField.HTTP_RESPONSE_CONTENT_LENGTH]: string;
- [SpanIndexedField.ORIGIN_TRANSACTION]: string;
- [SpanIndexedField.REPLAY_ID]: string;
- [SpanIndexedField.BROWSER_NAME]: string;
- [SpanIndexedField.USER]: string;
- [SpanIndexedField.USER_ID]: string;
- [SpanIndexedField.USER_EMAIL]: string;
- [SpanIndexedField.USER_USERNAME]: string;
- [SpanIndexedField.INP]: number;
- [SpanIndexedField.INP_SCORE]: number;
- [SpanIndexedField.INP_SCORE_WEIGHT]: number;
- [SpanIndexedField.TOTAL_SCORE]: number;
- [SpanIndexedField.RESPONSE_CODE]: string;
- [SpanIndexedField.CACHE_HIT]: '' | 'true' | 'false';
- [SpanIndexedField.CACHE_ITEM_SIZE]: number;
- [SpanIndexedField.TRACE_STATUS]: string;
- [SpanIndexedField.MESSAGING_MESSAGE_ID]: string;
- [SpanIndexedField.MESSAGING_MESSAGE_BODY_SIZE]: number;
- [SpanIndexedField.MESSAGING_MESSAGE_RECEIVE_LATENCY]: number;
- [SpanIndexedField.MESSAGING_MESSAGE_RETRY_COUNT]: number;
- [SpanIndexedField.MESSAGING_MESSAGE_DESTINATION_NAME]: string;
- };
- export type SpanIndexedPropery = keyof SpanIndexedResponse;
- // TODO: When convenient, remove this alias and use `IndexedResponse` everywhere
- export type SpanIndexedFieldTypes = SpanIndexedResponse;
- export type Op = SpanIndexedFieldTypes[SpanIndexedField.SPAN_OP];
- export enum SpanFunction {
- SPS = 'sps',
- SPM = 'spm',
- TIME_SPENT_PERCENTAGE = 'time_spent_percentage',
- HTTP_ERROR_COUNT = 'http_error_count',
- HTTP_RESPONSE_RATE = 'http_response_rate',
- CACHE_HIT_RATE = 'cache_hit_rate',
- CACHE_MISS_RATE = 'cache_miss_rate',
- COUNT_OP = 'count_op',
- 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;
- export enum MetricsFields {
- TRANSACTION_DURATION = 'transaction.duration',
- TRANSACTION = 'transaction',
- }
- export type MetricsNumberFields = MetricsFields.TRANSACTION_DURATION;
- export type MetricsStringFields = MetricsFields.TRANSACTION;
- export type MetricsFunctions = (typeof METRICS_FUNCTIONS)[number];
- export type MetricsResponse = {
- [Property in MetricsNumberFields as `${Aggregate}(${Property})`]: number;
- } & {
- [Property in MetricsStringFields as `${Property}`]: string;
- };
- export type MetricsProperty = keyof MetricsResponse;
- export type MetricsQueryFilters = {
- [Field in MetricsStringFields]?: string;
- } & {
- [SpanIndexedField.PROJECT_ID]?: string;
- };
|