Skip to content

Commit ba3e320

Browse files
legendecasdyladan
andauthored
feat(metrics): multi-instrument async callback support (#2966)
Co-authored-by: Daniel Dyla <[email protected]>
1 parent 610808d commit ba3e320

File tree

28 files changed

+1099
-247
lines changed

28 files changed

+1099
-247
lines changed

experimental/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ All notable changes to experimental packages in this project will be documented
88

99
* feat(metrics): metric readers and exporters now select aggregation temporality based on instrument type #2902 @seemk
1010
* refactor(metrics-sdk): rename InstrumentationLibrary -> InstrumentationScope #2959 @pichlermarc
11+
* feat(metrics): multi-instrument async callback support #2966 @legendecas
12+
* changes on `meter.createObservableCounter`, `meter.createObservableGauge`, `meter.createObservableUpDownCounter`
13+
* removed the second parameter `callback`
14+
* returns an `Observable` object on which callbacks can be registered or unregistered.
15+
* added `meter.addBatchObservableCallback` and `meter.removeBatchObservableCallback`.
1116

1217
### :rocket: (Enhancement)
1318

experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616

1717
import { Meter } from './types/Meter';
1818
import {
19-
MetricOptions,
20-
MetricAttributes,
19+
BatchObservableCallback,
2120
Counter,
2221
Histogram,
23-
UpDownCounter,
22+
MetricOptions,
2423
ObservableCallback,
24+
ObservableCounter,
25+
ObservableGauge,
26+
ObservableUpDownCounter,
27+
UpDownCounter,
28+
MetricAttributes,
29+
Observable,
2530
} from './types/Metric';
2631

2732
/**
@@ -32,67 +37,65 @@ export class NoopMeter implements Meter {
3237
constructor() {}
3338

3439
/**
35-
* Returns a constant noop histogram.
36-
* @param name the name of the metric.
37-
* @param [options] the metric options.
40+
* @see {@link Meter.createHistogram}
3841
*/
3942
createHistogram(_name: string, _options?: MetricOptions): Histogram {
4043
return NOOP_HISTOGRAM_METRIC;
4144
}
4245

4346
/**
44-
* Returns a constant noop counter.
45-
* @param name the name of the metric.
46-
* @param [options] the metric options.
47+
* @see {@link Meter.createCounter}
4748
*/
4849
createCounter(_name: string, _options?: MetricOptions): Counter {
4950
return NOOP_COUNTER_METRIC;
5051
}
5152

5253
/**
53-
* Returns a constant noop UpDownCounter.
54-
* @param name the name of the metric.
55-
* @param [options] the metric options.
54+
* @see {@link Meter.createUpDownCounter}
5655
*/
5756
createUpDownCounter(_name: string, _options?: MetricOptions): UpDownCounter {
5857
return NOOP_UP_DOWN_COUNTER_METRIC;
5958
}
6059

6160
/**
62-
* Returns a constant noop observable gauge.
63-
* @param name the name of the metric.
64-
* @param callback the observable gauge callback
65-
* @param [options] the metric options.
61+
* @see {@link Meter.createObservableGauge}
6662
*/
6763
createObservableGauge(
6864
_name: string,
69-
_callback: ObservableCallback,
7065
_options?: MetricOptions,
71-
): void {}
66+
): ObservableGauge {
67+
return NOOP_OBSERVABLE_GAUGE_METRIC;
68+
}
7269

7370
/**
74-
* Returns a constant noop observable counter.
75-
* @param name the name of the metric.
76-
* @param callback the observable counter callback
77-
* @param [options] the metric options.
71+
* @see {@link Meter.createObservableCounter}
7872
*/
7973
createObservableCounter(
8074
_name: string,
81-
_callback: ObservableCallback,
8275
_options?: MetricOptions,
83-
): void {}
76+
): ObservableCounter {
77+
return NOOP_OBSERVABLE_COUNTER_METRIC;
78+
}
8479

8580
/**
86-
* Returns a constant noop up down observable counter.
87-
* @param name the name of the metric.
88-
* @param callback the up down observable counter callback
89-
* @param [options] the metric options.
81+
* @see {@link Meter.createObservableUpDownCounter}
9082
*/
9183
createObservableUpDownCounter(
9284
_name: string,
93-
_callback: ObservableCallback,
9485
_options?: MetricOptions,
95-
): void {}
86+
): ObservableUpDownCounter {
87+
return NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC;
88+
}
89+
90+
/**
91+
* @see {@link Meter.addBatchObservableCallback}
92+
*/
93+
addBatchObservableCallback(_callback: BatchObservableCallback, _observables: Observable[]): void {}
94+
95+
/**
96+
* @see {@link Meter.removeBatchObservableCallback}
97+
*/
98+
removeBatchObservableCallback(_callback: BatchObservableCallback): void {}
9699
}
97100

98101
export class NoopMetric {}
@@ -109,9 +112,23 @@ export class NoopHistogramMetric extends NoopMetric implements Histogram {
109112
record(_value: number, _attributes: MetricAttributes): void {}
110113
}
111114

115+
export class NoopObservableMetric {
116+
addCallback(_callback: ObservableCallback) {}
117+
removeCallback(_callback: ObservableCallback) {}
118+
}
119+
120+
export class NoopObservableCounterMetric extends NoopObservableMetric implements ObservableCounter {}
121+
export class NoopObservableGaugeMetric extends NoopObservableMetric implements ObservableGauge {}
122+
export class NoopObservableUpDownCounterMetric extends NoopObservableMetric implements ObservableUpDownCounter {}
123+
112124
export const NOOP_METER = new NoopMeter();
113125

114126
// Synchronous instruments
115127
export const NOOP_COUNTER_METRIC = new NoopCounterMetric();
116128
export const NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric();
117129
export const NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric();
130+
131+
// Asynchronous instruments
132+
export const NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric();
133+
export const NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric();
134+
export const NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric();

experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { CounterOptions, HistogramOptions, UpDownCounterOptions } from '..';
1817
import {
18+
BatchObservableCallback,
1919
Counter,
2020
Histogram,
21-
ObservableCallback,
22-
ObservableCounterOptions,
23-
ObservableGaugeOptions,
24-
ObservableUpDownCounterOptions,
21+
MetricOptions,
22+
Observable,
23+
ObservableCounter,
24+
ObservableGauge,
25+
ObservableUpDownCounter,
2526
UpDownCounter,
2627
} from './Metric';
2728

@@ -48,7 +49,7 @@ export interface Meter {
4849
* @param name the name of the metric.
4950
* @param [options] the metric options.
5051
*/
51-
createHistogram(name: string, options?: HistogramOptions): Histogram;
52+
createHistogram(name: string, options?: MetricOptions): Histogram;
5253

5354
/**
5455
* Creates a new `Counter` metric. Generally, this kind of metric when the
@@ -57,7 +58,7 @@ export interface Meter {
5758
* @param name the name of the metric.
5859
* @param [options] the metric options.
5960
*/
60-
createCounter(name: string, options?: CounterOptions): Counter;
61+
createCounter(name: string, options?: MetricOptions): Counter;
6162

6263
/**
6364
* Creates a new `UpDownCounter` metric. UpDownCounter is a synchronous
@@ -76,50 +77,71 @@ export interface Meter {
7677
* @param name the name of the metric.
7778
* @param [options] the metric options.
7879
*/
79-
createUpDownCounter(name: string, options?: UpDownCounterOptions): UpDownCounter;
80+
createUpDownCounter(name: string, options?: MetricOptions): UpDownCounter;
8081

8182
/**
8283
* Creates a new `ObservableGauge` metric.
8384
*
8485
* The callback SHOULD be safe to be invoked concurrently.
8586
*
8687
* @param name the name of the metric.
87-
* @param callback the observable callback
8888
* @param [options] the metric options.
8989
*/
9090
createObservableGauge(
9191
name: string,
92-
callback: ObservableCallback,
93-
options?: ObservableGaugeOptions
94-
): void;
92+
options?: MetricOptions
93+
): ObservableGauge;
9594

9695
/**
9796
* Creates a new `ObservableCounter` metric.
9897
*
9998
* The callback SHOULD be safe to be invoked concurrently.
10099
*
101100
* @param name the name of the metric.
102-
* @param callback the observable callback
103101
* @param [options] the metric options.
104102
*/
105103
createObservableCounter(
106104
name: string,
107-
callback: ObservableCallback,
108-
options?: ObservableCounterOptions
109-
): void;
105+
options?: MetricOptions
106+
): ObservableCounter;
110107

111108
/**
112109
* Creates a new `ObservableUpDownCounter` metric.
113110
*
114111
* The callback SHOULD be safe to be invoked concurrently.
115112
*
116113
* @param name the name of the metric.
117-
* @param callback the observable callback
118114
* @param [options] the metric options.
119115
*/
120116
createObservableUpDownCounter(
121117
name: string,
122-
callback: ObservableCallback,
123-
options?: ObservableUpDownCounterOptions
124-
): void;
118+
options?: MetricOptions
119+
): ObservableUpDownCounter;
120+
121+
/**
122+
* Sets up a function that will be called whenever a metric collection is
123+
* initiated.
124+
*
125+
* If the function is already in the list of callbacks for this Observable,
126+
* the function is not added a second time.
127+
*
128+
* Only the associated observables can be observed in the callback.
129+
* Measurements of observables that are not associated observed in the
130+
* callback are dropped.
131+
*
132+
* @param callback the batch observable callback
133+
* @param observables the observables associated with this batch observable callback
134+
*/
135+
addBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]): void;
136+
137+
/**
138+
* Removes a callback previously registered with {@link Meter.addBatchObservableCallback}.
139+
*
140+
* The callback to be removed is identified using a combination of the callback itself,
141+
* and the set of the observables associated with it.
142+
*
143+
* @param callback the batch observable callback
144+
* @param observables the observables associated with this batch observable callback
145+
*/
146+
removeBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]): void;
125147
}

experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import { Context } from '@opentelemetry/api';
18-
import { ObservableResult } from './ObservableResult';
18+
import { BatchObservableResult, ObservableResult } from './ObservableResult';
1919

2020
/**
2121
* Options needed for metric creation
@@ -40,13 +40,6 @@ export interface MetricOptions {
4040
valueType?: ValueType;
4141
}
4242

43-
export type CounterOptions = MetricOptions;
44-
export type UpDownCounterOptions = MetricOptions;
45-
export type ObservableGaugeOptions = MetricOptions;
46-
export type ObservableCounterOptions = MetricOptions;
47-
export type ObservableUpDownCounterOptions = MetricOptions;
48-
export type HistogramOptions = MetricOptions;
49-
5043
/** The Type of value. It describes how the data is reported. */
5144
export enum ValueType {
5245
INT,
@@ -98,3 +91,26 @@ export type MetricAttributes = { [key: string]: string };
9891
* The observable callback for Observable instruments.
9992
*/
10093
export type ObservableCallback = (observableResult: ObservableResult) => void | Promise<void>;
94+
95+
/**
96+
* The observable callback for a batch of Observable instruments.
97+
*/
98+
export type BatchObservableCallback = (observableResult: BatchObservableResult) => void | Promise<void>;
99+
100+
export interface Observable {
101+
/**
102+
* Sets up a function that will be called whenever a metric collection is initiated.
103+
*
104+
* If the function is already in the list of callbacks for this Observable, the function is not added a second time.
105+
*/
106+
addCallback(callback: ObservableCallback): void;
107+
108+
/**
109+
* Removes a callback previously registered with {@link Observable.addCallback}.
110+
*/
111+
removeCallback(callback: ObservableCallback): void;
112+
}
113+
114+
export type ObservableCounter = Observable;
115+
export type ObservableUpDownCounter = Observable;
116+
export type ObservableGauge = Observable;

experimental/packages/opentelemetry-api-metrics/src/types/ObservableResult.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { MetricAttributes } from './Metric';
17+
import { MetricAttributes, Observable } from './Metric';
1818

1919
/**
20-
* Interface that is being used in callback function for Observable Metric
20+
* Interface that is being used in callback function for Observable Metric.
2121
*/
2222
export interface ObservableResult {
2323
/**
@@ -30,3 +30,19 @@ export interface ObservableResult {
3030
*/
3131
observe(value: number, attributes?: MetricAttributes): void;
3232
}
33+
34+
/**
35+
* Interface that is being used in batch observable callback function.
36+
*/
37+
export interface BatchObservableResult {
38+
/**
39+
* Observe a measurement of the value associated with the given attributes.
40+
*
41+
* @param metric The observable metric to be observed.
42+
* @param value The value to be observed.
43+
* @param attributes The attributes associated with the value. If more than
44+
* one values associated with the same attributes values, SDK may pick the
45+
* last one or simply drop the entire observable result.
46+
*/
47+
observe(metric: Observable, value: number, attributes?: MetricAttributes): void;
48+
}

0 commit comments

Comments
 (0)