Skip to content

Commit 59db749

Browse files
authored
feat(metrics): Add interfaces for metrics (#9698)
Not adding any tests for `createMetricEnvelope` yet because the type for `metricAggregate` is going to change, just added it as boilerplate. In the next PR I'll be implementing a metrics aggregator class which lives on the client. This is responsible for bucketing metrics and incrementally flushing them out. https://develop.sentry.dev/delightful-developer-metrics/ https://develop.sentry.dev/delightful-developer-metrics/sending-metrics-sdk/
1 parent 27f6ae1 commit 59db749

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

packages/core/src/metrics/index.ts

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import type { DsnComponents, DynamicSamplingContext, SdkMetadata, StatsdEnvelope, StatsdItem } from '@sentry/types';
2+
import { createEnvelope, dropUndefinedKeys, dsnToString } from '@sentry/utils';
3+
4+
/**
5+
* Create envelope from a metric aggregate.
6+
*/
7+
export function createMetricEnvelope(
8+
// TODO(abhi): Add type for this
9+
metricAggregate: string,
10+
dynamicSamplingContext?: Partial<DynamicSamplingContext>,
11+
metadata?: SdkMetadata,
12+
tunnel?: string,
13+
dsn?: DsnComponents,
14+
): StatsdEnvelope {
15+
const headers: StatsdEnvelope[0] = {
16+
sent_at: new Date().toISOString(),
17+
};
18+
19+
if (metadata && metadata.sdk) {
20+
headers.sdk = {
21+
name: metadata.sdk.name,
22+
version: metadata.sdk.version,
23+
};
24+
}
25+
26+
if (!!tunnel && !!dsn) {
27+
headers.dsn = dsnToString(dsn);
28+
}
29+
30+
if (dynamicSamplingContext) {
31+
headers.trace = dropUndefinedKeys(dynamicSamplingContext) as DynamicSamplingContext;
32+
}
33+
34+
const item = createMetricEnvelopeItem(metricAggregate);
35+
return createEnvelope<StatsdEnvelope>(headers, [item]);
36+
}
37+
38+
function createMetricEnvelopeItem(metricAggregate: string): StatsdItem {
39+
const metricHeaders: StatsdItem[0] = {
40+
type: 'statsd',
41+
};
42+
return [metricHeaders, metricAggregate];
43+
}

packages/types/src/envelope.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,11 @@ export type ReplayEnvelope = [ReplayEnvelopeHeaders, [ReplayEventItem, ReplayRec
109109
export type CheckInEnvelope = BaseEnvelope<CheckInEnvelopeHeaders, CheckInItem>;
110110
export type StatsdEnvelope = BaseEnvelope<StatsdEnvelopeHeaders, StatsdItem>;
111111

112-
export type Envelope = EventEnvelope | SessionEnvelope | ClientReportEnvelope | ReplayEnvelope | CheckInEnvelope;
112+
export type Envelope =
113+
| EventEnvelope
114+
| SessionEnvelope
115+
| ClientReportEnvelope
116+
| ReplayEnvelope
117+
| CheckInEnvelope
118+
| StatsdEnvelope;
113119
export type EnvelopeItem = Envelope[1][number];

packages/types/src/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ export type {
4242
UserFeedbackItem,
4343
CheckInItem,
4444
CheckInEnvelope,
45+
StatsdItem,
46+
StatsdEnvelope,
4547
} from './envelope';
4648
export type { ExtendedError } from './error';
4749
export type { Event, EventHint, EventType, ErrorEvent, TransactionEvent } from './event';
@@ -136,3 +138,4 @@ export type {
136138

137139
export type { BrowserClientReplayOptions, BrowserClientProfilingOptions } from './browseroptions';
138140
export type { CheckIn, MonitorConfig, FinishedCheckIn, InProgressCheckIn, SerializedCheckIn } from './checkin';
141+
export type { Metric, CounterMetric, GaugeMetric, DistributionMetric, SetMetric } from './metrics';

packages/types/src/metrics.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { MeasurementUnit } from './measurement';
2+
import type { Primitive } from './misc';
3+
4+
export interface BaseMetric {
5+
name: string;
6+
timestamp: number;
7+
unit?: MeasurementUnit;
8+
tags?: { [key: string]: Primitive };
9+
}
10+
11+
export interface CounterMetric extends BaseMetric {
12+
value: number;
13+
}
14+
15+
export interface GaugeMetric extends BaseMetric {
16+
value: number;
17+
first: number;
18+
min: number;
19+
max: number;
20+
sum: number;
21+
count: number;
22+
}
23+
24+
export interface DistributionMetric extends BaseMetric {
25+
value: number[];
26+
}
27+
28+
export interface SetMetric extends BaseMetric {
29+
value: Set<number>;
30+
}
31+
32+
export type Metric = CounterMetric | GaugeMetric | DistributionMetric | SetMetric;

0 commit comments

Comments
 (0)