diff --git a/packages/core/src/metrics/index.ts b/packages/core/src/metrics/index.ts new file mode 100644 index 000000000000..3cfeae37e03f --- /dev/null +++ b/packages/core/src/metrics/index.ts @@ -0,0 +1,43 @@ +import type { DsnComponents, DynamicSamplingContext, SdkMetadata, StatsdEnvelope, StatsdItem } from '@sentry/types'; +import { createEnvelope, dropUndefinedKeys, dsnToString } from '@sentry/utils'; + +/** + * Create envelope from a metric aggregate. + */ +export function createMetricEnvelope( + // TODO(abhi): Add type for this + metricAggregate: string, + dynamicSamplingContext?: Partial, + metadata?: SdkMetadata, + tunnel?: string, + dsn?: DsnComponents, +): StatsdEnvelope { + const headers: StatsdEnvelope[0] = { + sent_at: new Date().toISOString(), + }; + + if (metadata && metadata.sdk) { + headers.sdk = { + name: metadata.sdk.name, + version: metadata.sdk.version, + }; + } + + if (!!tunnel && !!dsn) { + headers.dsn = dsnToString(dsn); + } + + if (dynamicSamplingContext) { + headers.trace = dropUndefinedKeys(dynamicSamplingContext) as DynamicSamplingContext; + } + + const item = createMetricEnvelopeItem(metricAggregate); + return createEnvelope(headers, [item]); +} + +function createMetricEnvelopeItem(metricAggregate: string): StatsdItem { + const metricHeaders: StatsdItem[0] = { + type: 'statsd', + }; + return [metricHeaders, metricAggregate]; +} diff --git a/packages/types/src/envelope.ts b/packages/types/src/envelope.ts index d479b9f8a4e9..fbe593dd21f9 100644 --- a/packages/types/src/envelope.ts +++ b/packages/types/src/envelope.ts @@ -109,5 +109,11 @@ export type ReplayEnvelope = [ReplayEnvelopeHeaders, [ReplayEventItem, ReplayRec export type CheckInEnvelope = BaseEnvelope; export type StatsdEnvelope = BaseEnvelope; -export type Envelope = EventEnvelope | SessionEnvelope | ClientReportEnvelope | ReplayEnvelope | CheckInEnvelope; +export type Envelope = + | EventEnvelope + | SessionEnvelope + | ClientReportEnvelope + | ReplayEnvelope + | CheckInEnvelope + | StatsdEnvelope; export type EnvelopeItem = Envelope[1][number]; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 627879493365..615bf71ff785 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -42,6 +42,8 @@ export type { UserFeedbackItem, CheckInItem, CheckInEnvelope, + StatsdItem, + StatsdEnvelope, } from './envelope'; export type { ExtendedError } from './error'; export type { Event, EventHint, EventType, ErrorEvent, TransactionEvent } from './event'; @@ -136,3 +138,4 @@ export type { export type { BrowserClientReplayOptions, BrowserClientProfilingOptions } from './browseroptions'; export type { CheckIn, MonitorConfig, FinishedCheckIn, InProgressCheckIn, SerializedCheckIn } from './checkin'; +export type { Metric, CounterMetric, GaugeMetric, DistributionMetric, SetMetric } from './metrics'; diff --git a/packages/types/src/metrics.ts b/packages/types/src/metrics.ts new file mode 100644 index 000000000000..b55096950b2f --- /dev/null +++ b/packages/types/src/metrics.ts @@ -0,0 +1,32 @@ +import type { MeasurementUnit } from './measurement'; +import type { Primitive } from './misc'; + +export interface BaseMetric { + name: string; + timestamp: number; + unit?: MeasurementUnit; + tags?: { [key: string]: Primitive }; +} + +export interface CounterMetric extends BaseMetric { + value: number; +} + +export interface GaugeMetric extends BaseMetric { + value: number; + first: number; + min: number; + max: number; + sum: number; + count: number; +} + +export interface DistributionMetric extends BaseMetric { + value: number[]; +} + +export interface SetMetric extends BaseMetric { + value: Set; +} + +export type Metric = CounterMetric | GaugeMetric | DistributionMetric | SetMetric;