Skip to content

Commit 0f14be9

Browse files
authored
Merge branch 'main' into docs/sdk-metrics
2 parents c1485bd + b73c29d commit 0f14be9

15 files changed

Lines changed: 261 additions & 121 deletions

File tree

experimental/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ All notable changes to experimental packages in this project will be documented
3838
* `NoopObservableMetric`
3939
* `NoopObservableUpDownCounterMetric`
4040
* `NoopUpDownCounterMetric`
41+
* feat(sdk-metrics): align MetricReader with specification and other language implementations [#3225](https://github.com/open-telemetry/opentelemetry-js/pull/3225) @pichlermarc
4142
* chore(sdk-metrics): remove accidental export of the SDK `Meter` class [#3243](https://github.com/open-telemetry/opentelemetry-js/pull/3243) @pichlermarc
4243

4344
### :rocket: (Enhancement)

experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ import * as assert from 'assert';
2020
import * as grpc from '@grpc/grpc-js';
2121
import { VERSION } from '@opentelemetry/core';
2222
import {
23-
Aggregation,
24-
AggregationTemporality,
2523
ExplicitBucketHistogramAggregation,
2624
MeterProvider,
2725
MetricReader,
@@ -30,14 +28,6 @@ import {
3028
import { IKeyValue, IMetric, IResource } from '@opentelemetry/otlp-transformer';
3129

3230
class TestMetricReader extends MetricReader {
33-
selectAggregation() {
34-
return Aggregation.Default();
35-
}
36-
37-
selectAggregationTemporality() {
38-
return AggregationTemporality.CUMULATIVE;
39-
}
40-
4131
protected onForceFlush(): Promise<void> {
4232
return Promise.resolve(undefined);
4333
}

experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import { Resource } from '@opentelemetry/resources';
2727
import * as assert from 'assert';
2828
import { InstrumentationScope, VERSION } from '@opentelemetry/core';
2929
import {
30-
Aggregation,
31-
AggregationTemporality,
3230
ExplicitBucketHistogramAggregation,
3331
MeterProvider,
3432
MetricReader,
@@ -57,14 +55,6 @@ class TestMetricReader extends MetricReader {
5755
protected onShutdown(): Promise<void> {
5856
return Promise.resolve(undefined);
5957
}
60-
61-
selectAggregation() {
62-
return Aggregation.Default();
63-
}
64-
65-
selectAggregationTemporality() {
66-
return AggregationTemporality.CUMULATIVE;
67-
}
6858
}
6959

7060
export const HISTOGRAM_AGGREGATION_VIEW = new View({

experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import {
2424
import { Resource } from '@opentelemetry/resources';
2525
import * as assert from 'assert';
2626
import {
27-
Aggregation,
28-
AggregationTemporality,
2927
ExplicitBucketHistogramAggregation,
3028
MeterProvider,
3129
MetricReader,
@@ -35,14 +33,6 @@ import { IExportMetricsServiceRequest, IKeyValue, IMetric } from '@opentelemetry
3533
import { Stream } from 'stream';
3634

3735
export class TestMetricReader extends MetricReader {
38-
selectAggregation() {
39-
return Aggregation.Default();
40-
}
41-
42-
selectAggregationTemporality() {
43-
return AggregationTemporality.CUMULATIVE;
44-
}
45-
4636
protected onForceFlush(): Promise<void> {
4737
return Promise.resolve(undefined);
4838
}

experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ export class PrometheusExporter extends MetricReader {
5555
* @param callback Callback to be called after a server was started
5656
*/
5757
constructor(config: ExporterConfig = {}, callback?: () => void) {
58-
super();
58+
super({
59+
aggregationSelector: _instrumentType => Aggregation.Default(),
60+
aggregationTemporalitySelector: _instrumentType => AggregationTemporality.CUMULATIVE
61+
});
5962
this._host =
6063
config.host ||
6164
process.env.OTEL_EXPORTER_PROMETHEUS_HOST ||
@@ -90,14 +93,6 @@ export class PrometheusExporter extends MetricReader {
9093
}
9194
}
9295

93-
selectAggregation(): Aggregation {
94-
return Aggregation.Default();
95-
}
96-
97-
selectAggregationTemporality(): AggregationTemporality {
98-
return AggregationTemporality.CUMULATIVE;
99-
}
100-
10196
override async onForceFlush(): Promise<void> {
10297
/** do nothing */
10398
}

experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,10 @@ const attributes = {
4040

4141
class TestMetricReader extends MetricReader {
4242
constructor() {
43-
super();
44-
}
45-
46-
selectAggregationTemporality() {
47-
return AggregationTemporality.CUMULATIVE;
48-
}
49-
50-
selectAggregation() {
51-
return Aggregation.Default();
43+
super({
44+
aggregationTemporalitySelector: _instrumentType => AggregationTemporality.CUMULATIVE,
45+
aggregationSelector: _instrumentType => Aggregation.Default()
46+
});
5247
}
5348

5449
async onForceFlush() {}

experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ export type AggregationSelector = (instrumentType: InstrumentType) => Aggregatio
2727
* Aggregation temporality selector based on metric instrument types.
2828
*/
2929
export type AggregationTemporalitySelector = (instrumentType: InstrumentType) => AggregationTemporality;
30+
31+
export const DEFAULT_AGGREGATION_SELECTOR: AggregationSelector = _instrumentType => Aggregation.Default();
32+
export const DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR: AggregationTemporalitySelector = _instrumentType => AggregationTemporality.CUMULATIVE;

experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
ExportResult,
2121
} from '@opentelemetry/core';
2222
import { InstrumentType } from '../InstrumentDescriptor';
23+
import { Aggregation } from '../view/Aggregation';
2324

2425
/**
2526
* An interface that allows different metric services to export recorded data
@@ -45,7 +46,13 @@ export interface PushMetricExporter {
4546
* Select the {@link AggregationTemporality} for the given
4647
* {@link InstrumentType} for this exporter.
4748
*/
48-
selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality;
49+
selectAggregationTemporality?(instrumentType: InstrumentType): AggregationTemporality;
50+
51+
/**
52+
* Select the {@link Aggregation} for the given
53+
* {@link InstrumentType} for this exporter.
54+
*/
55+
selectAggregation?(instrumentType: InstrumentType): Aggregation;
4956

5057
/**
5158
* Returns a promise which resolves when the last exportation is completed.

experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,32 @@ import { MetricProducer } from './MetricProducer';
2020
import { CollectionResult } from './MetricData';
2121
import { callWithTimeout } from '../utils';
2222
import { InstrumentType } from '../InstrumentDescriptor';
23-
import { CollectionOptions, ForceFlushOptions, ShutdownOptions } from '../types';
23+
import {
24+
CollectionOptions,
25+
ForceFlushOptions,
26+
ShutdownOptions
27+
} from '../types';
2428
import { Aggregation } from '../view/Aggregation';
29+
import {
30+
AggregationSelector,
31+
AggregationTemporalitySelector,
32+
DEFAULT_AGGREGATION_SELECTOR,
33+
DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR
34+
} from './AggregationSelector';
35+
36+
export interface MetricReaderOptions {
37+
/**
38+
* Aggregation selector based on metric instrument types. If no views are
39+
* configured for a metric instrument, a per-metric-reader aggregation is
40+
* selected with this selector.
41+
*/
42+
aggregationSelector?: AggregationSelector;
43+
/**
44+
* Aggregation temporality selector based on metric instrument types. If
45+
* not configured, cumulative is used for all instruments.
46+
*/
47+
aggregationTemporalitySelector?: AggregationTemporalitySelector;
48+
}
2549

2650
/**
2751
* A registered reader of metrics that, when linked to a {@link MetricProducer}, offers global
@@ -33,6 +57,15 @@ export abstract class MetricReader {
3357
private _shutdown = false;
3458
// MetricProducer used by this instance.
3559
private _metricProducer?: MetricProducer;
60+
private readonly _aggregationTemporalitySelector: AggregationTemporalitySelector;
61+
private readonly _aggregationSelector: AggregationSelector;
62+
63+
constructor(options?: MetricReaderOptions) {
64+
this._aggregationSelector = options?.aggregationSelector ??
65+
DEFAULT_AGGREGATION_SELECTOR;
66+
this._aggregationTemporalitySelector = options?.aggregationTemporalitySelector ??
67+
DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR;
68+
}
3669

3770
/**
3871
* Set the {@link MetricProducer} used by this instance.
@@ -51,13 +84,17 @@ export abstract class MetricReader {
5184
* Select the {@link Aggregation} for the given {@link InstrumentType} for this
5285
* reader.
5386
*/
54-
abstract selectAggregation(instrumentType: InstrumentType): Aggregation;
87+
selectAggregation(instrumentType: InstrumentType): Aggregation {
88+
return this._aggregationSelector(instrumentType);
89+
}
5590

5691
/**
5792
* Select the {@link AggregationTemporality} for the given
5893
* {@link InstrumentType} for this reader.
5994
*/
60-
abstract selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality;
95+
selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality {
96+
return this._aggregationTemporalitySelector(instrumentType);
97+
}
6198

6299
/**
63100
* Handle once the SDK has initialized this {@link MetricReader}

experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,13 @@ import {
2121
unrefTimer
2222
} from '@opentelemetry/core';
2323
import { MetricReader } from './MetricReader';
24-
import { AggregationTemporality } from './AggregationTemporality';
25-
import { InstrumentType } from '../InstrumentDescriptor';
2624
import { PushMetricExporter } from './MetricExporter';
27-
import { callWithTimeout, TimeoutError } from '../utils';
28-
import { Aggregation } from '../view/Aggregation';
29-
import { AggregationSelector } from './AggregationSelector';
25+
import {
26+
callWithTimeout,
27+
TimeoutError
28+
} from '../utils';
3029

3130
export type PeriodicExportingMetricReaderOptions = {
32-
/**
33-
* Aggregation selector based on metric instrument types. If no views are
34-
* configured for a metric instrument, a per-metric-reader aggregation is
35-
* selected with this selector.
36-
*/
37-
aggregationSelector?: AggregationSelector;
3831
/**
3932
* The backing exporter for the metric reader.
4033
*/
@@ -50,8 +43,6 @@ export type PeriodicExportingMetricReaderOptions = {
5043
exportTimeoutMillis?: number;
5144
};
5245

53-
const DEFAULT_AGGREGATION_SELECTOR: AggregationSelector = Aggregation.Default;
54-
5546
/**
5647
* {@link MetricReader} which collects metrics based on a user-configurable time interval, and passes the metrics to
5748
* the configured {@link PushMetricExporter}
@@ -61,10 +52,12 @@ export class PeriodicExportingMetricReader extends MetricReader {
6152
private _exporter: PushMetricExporter;
6253
private readonly _exportInterval: number;
6354
private readonly _exportTimeout: number;
64-
private readonly _aggregationSelector: AggregationSelector;
6555

6656
constructor(options: PeriodicExportingMetricReaderOptions) {
67-
super();
57+
super({
58+
aggregationSelector: options.exporter.selectAggregation?.bind(options.exporter),
59+
aggregationTemporalitySelector: options.exporter.selectAggregationTemporality?.bind(options.exporter)
60+
});
6861

6962
if (options.exportIntervalMillis !== undefined && options.exportIntervalMillis <= 0) {
7063
throw Error('exportIntervalMillis must be greater than 0');
@@ -83,7 +76,6 @@ export class PeriodicExportingMetricReader extends MetricReader {
8376
this._exportInterval = options.exportIntervalMillis ?? 60000;
8477
this._exportTimeout = options.exportTimeoutMillis ?? 30000;
8578
this._exporter = options.exporter;
86-
this._aggregationSelector = options.aggregationSelector ?? DEFAULT_AGGREGATION_SELECTOR;
8779
}
8880

8981
private async _runOnce(): Promise<void> {
@@ -98,9 +90,9 @@ export class PeriodicExportingMetricReader extends MetricReader {
9890
if (result.code !== ExportResultCode.SUCCESS) {
9991
reject(
10092
result.error ??
101-
new Error(
102-
`PeriodicExportingMetricReader: metrics export failed (error ${result.error})`
103-
)
93+
new Error(
94+
`PeriodicExportingMetricReader: metrics export failed (error ${result.error})`
95+
)
10496
);
10597
} else {
10698
resolve();
@@ -137,18 +129,4 @@ export class PeriodicExportingMetricReader extends MetricReader {
137129

138130
await this._exporter.shutdown();
139131
}
140-
141-
/**
142-
* @inheritdoc
143-
*/
144-
selectAggregation(instrumentType: InstrumentType): Aggregation {
145-
return this._aggregationSelector(instrumentType);
146-
}
147-
148-
/**
149-
* @inheritdoc
150-
*/
151-
selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality {
152-
return this._exporter.selectAggregationTemporality(instrumentType);
153-
}
154132
}

0 commit comments

Comments
 (0)