1
1
import type {
2
2
Client ,
3
+ DurationUnit ,
3
4
MeasurementUnit ,
4
5
MetricsAggregator as MetricsAggregatorInterface ,
5
6
Primitive ,
6
7
} from '@sentry/types' ;
7
- import { getGlobalSingleton , logger } from '@sentry/utils' ;
8
+ import { getGlobalSingleton , logger , timestampInSeconds } from '@sentry/utils' ;
8
9
import { getClient } from '../currentScopes' ;
9
10
import { DEBUG_BUILD } from '../debug-build' ;
11
+ import { startInactiveSpan } from '../tracing' ;
12
+ import { handleCallbackErrors } from '../utils/handleCallbackErrors' ;
10
13
import { getActiveSpan , getRootSpan , spanToJSON } from '../utils/spanUtils' ;
11
14
import { COUNTER_METRIC_TYPE , DISTRIBUTION_METRIC_TYPE , GAUGE_METRIC_TYPE , SET_METRIC_TYPE } from './constants' ;
12
15
import type { MetricType } from './types' ;
@@ -102,6 +105,50 @@ function distribution(aggregator: MetricsAggregatorConstructor, name: string, va
102
105
addToMetricsAggregator ( aggregator , DISTRIBUTION_METRIC_TYPE , name , ensureNumber ( value ) , data ) ;
103
106
}
104
107
108
+ function timing (
109
+ aggregator : MetricsAggregatorConstructor ,
110
+ name : string ,
111
+ value : number ,
112
+ unit ?: DurationUnit ,
113
+ data ?: Omit < MetricData , 'unit' > ,
114
+ ) : void ;
115
+ function timing < T > (
116
+ aggregator : MetricsAggregatorConstructor ,
117
+ name : string ,
118
+ value : ( ) => T ,
119
+ unit ?: DurationUnit ,
120
+ data ?: Omit < MetricData , 'unit' > ,
121
+ ) : T ;
122
+ function timing < T = void > (
123
+ aggregator : MetricsAggregatorConstructor ,
124
+ name : string ,
125
+ value : number | ( ( ) => T ) ,
126
+ unit : DurationUnit = 'second' ,
127
+ data ?: Omit < MetricData , 'unit' > ,
128
+ ) : T | void {
129
+ // callback form
130
+ if ( typeof value === 'function' ) {
131
+ const startTime = timestampInSeconds ( ) ;
132
+ const span = startInactiveSpan ( { op : 'metrics.timing' , name, startTime } ) ;
133
+
134
+ return handleCallbackErrors (
135
+ ( ) => value ( ) ,
136
+ ( ) => {
137
+ // no special error handling necessary
138
+ } ,
139
+ ( ) => {
140
+ const endTime = timestampInSeconds ( ) ;
141
+ const timeDiff = endTime - startTime ;
142
+ distribution ( aggregator , name , timeDiff , { ...data , unit } ) ;
143
+ span . end ( endTime ) ;
144
+ } ,
145
+ ) ;
146
+ }
147
+
148
+ // value form
149
+ distribution ( aggregator , name , value , { ...data , unit } ) ;
150
+ }
151
+
105
152
/**
106
153
* Adds a value to a set metric. Value must be a string or integer.
107
154
*
@@ -125,6 +172,7 @@ export const metrics = {
125
172
distribution,
126
173
set,
127
174
gauge,
175
+ timing,
128
176
/**
129
177
* @ignore This is for internal use only.
130
178
*/
0 commit comments