Skip to content

Commit c635ba6

Browse files
committed
feat: bootstrap views api
1 parent d128f0f commit c635ba6

14 files changed

Lines changed: 771 additions & 225 deletions

File tree

experimental/packages/opentelemetry-sdk-metrics-base/src/Instruments.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,22 @@ export enum InstrumentType {
2929
OBSERVABLE_UP_DOWN_COUNTER = 'OBSERVABLE_UP_DOWN_COUNTER',
3030
}
3131

32+
export interface InstrumentDescriptor {
33+
readonly name: string;
34+
readonly description: string;
35+
readonly unit: string;
36+
readonly type: InstrumentType;
37+
readonly valueType: metrics.ValueType;
38+
}
39+
3240
export class SyncInstrument {
3341
constructor(private _meter: Meter, private _name: string) { }
3442

3543
getName(): string {
3644
return this._name;
3745
}
3846

39-
47+
4048
aggregate(value: number, attributes: metrics.Attributes = {}, ctx: api.Context = api.context.active()) {
4149
this._meter.aggregate(this, {
4250
value,

experimental/packages/opentelemetry-sdk-metrics-base/src/MeterProvider.ts

Lines changed: 107 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -21,128 +21,131 @@ import { Measurement } from './Measurement';
2121
import { Meter } from './Meter';
2222
import { MetricExporter } from './MetricExporter';
2323
import { MetricReader } from './MetricReader';
24-
import { View } from './View';
24+
import { InstrumentSelector } from './view/InstrumentSelector';
25+
import { MeterSelector } from './view/MeterSelector';
26+
import { View } from './view/View';
27+
import { ViewRegistry } from './view/ViewRegistry';
2528

2629
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#meterprovider
2730

2831
export type MeterProviderOptions = {
29-
resource?: Resource;
32+
resource?: Resource;
3033
}
3134

3235
export class MeterProvider {
33-
private _resource: Resource;
34-
private _shutdown = false;
35-
private _metricReaders: MetricReader[] = [];
36-
private _metricExporters: MetricExporter[] = [];
37-
private _views: View[] = [];
38-
39-
constructor(options: MeterProviderOptions) {
40-
this._resource = options.resource ?? Resource.empty();
36+
private _resource: Resource;
37+
private _shutdown = false;
38+
private _metricReaders: MetricReader[] = [];
39+
private _metricExporters: MetricExporter[] = [];
40+
private readonly _viewRegistry = new ViewRegistry();
41+
42+
constructor(options: MeterProviderOptions) {
43+
this._resource = options.resource ?? Resource.empty();
44+
}
45+
46+
/**
47+
* **Unstable**
48+
*
49+
* This method is only here to prevent typescript from complaining and may be removed.
50+
*/
51+
getResource() {
52+
return this._resource;
53+
}
54+
55+
getMeter(name: string, version = '', options: metrics.MeterOptions = {}): metrics.Meter {
56+
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#meter-creation
57+
if (this._shutdown) {
58+
api.diag.warn('A shutdown MeterProvider cannot provide a Meter')
59+
return metrics.NOOP_METER;
4160
}
4261

43-
/**
44-
* **Unstable**
45-
*
46-
* This method is only here to prevent typescript from complaining and may be removed.
47-
*/
48-
getResource() {
49-
return this._resource;
62+
// Spec leaves it unspecified if creating a meter with duplicate
63+
// name/version returns the same meter. We create a new one here
64+
// for simplicity. This may change in the future.
65+
// TODO: consider returning the same meter if the same name/version is used
66+
return new Meter(this, { name, version }, options.schemaUrl);
67+
}
68+
69+
addMetricReader(metricReader: MetricReader) {
70+
this._metricReaders.push(metricReader);
71+
}
72+
73+
addView(view: View, instrumentSelector: InstrumentSelector, meterSelector: MeterSelector) {
74+
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view
75+
this._viewRegistry.addView(view, instrumentSelector, meterSelector);
76+
}
77+
78+
/**
79+
* Flush all buffered data and shut down the MeterProvider and all exporters and metric readers.
80+
* Returns a promise which is resolved when all flushes are complete.
81+
*
82+
* TODO: return errors to caller somehow?
83+
*/
84+
async shutdown(): Promise<void> {
85+
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#shutdown
86+
87+
if (this._shutdown) {
88+
api.diag.warn('shutdown may only be called once per MeterProvider');
89+
return;
5090
}
5191

52-
getMeter(name: string, version = '', options: metrics.MeterOptions = {}): metrics.Meter {
53-
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#meter-creation
54-
if (this._shutdown) {
55-
api.diag.warn('A shutdown MeterProvider cannot provide a Meter')
56-
return metrics.NOOP_METER;
92+
// TODO add a timeout - spec leaves it up the the SDK if this is configurable
93+
this._shutdown = true;
94+
95+
// Shut down all exporters and readers.
96+
// Log all Errors.
97+
for (const exporter of this._metricExporters) {
98+
try {
99+
await exporter.shutdown();
100+
} catch (e) {
101+
if (e instanceof Error) {
102+
api.diag.error(`Error shutting down: ${e.message}`)
57103
}
58-
59-
// Spec leaves it unspecified if creating a meter with duplicate
60-
// name/version returns the same meter. We create a new one here
61-
// for simplicity. This may change in the future.
62-
// TODO: consider returning the same meter if the same name/version is used
63-
return new Meter(this, { name, version }, options.schemaUrl);
64-
}
65-
66-
addMetricReader(metricReader: MetricReader) {
67-
this._metricReaders.push(metricReader);
104+
}
68105
}
69-
70-
addView(view: View) {
71-
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view
72-
this._views.push(view);
106+
}
107+
108+
/**
109+
* Notifies all exporters and metric readers to flush any buffered data.
110+
* Returns a promise which is resolved when all flushes are complete.
111+
*
112+
* TODO: return errors to caller somehow?
113+
*/
114+
async forceFlush(): Promise<void> {
115+
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#forceflush
116+
117+
// TODO add a timeout - spec leaves it up the the SDK if this is configurable
118+
119+
// do not flush after shutdown
120+
if (this._shutdown) {
121+
api.diag.warn('invalid attempt to force flush after shutdown')
122+
return;
73123
}
74124

75-
/**
76-
* Flush all buffered data and shut down the MeterProvider and all exporters and metric readers.
77-
* Returns a promise which is resolved when all flushes are complete.
78-
*
79-
* TODO: return errors to caller somehow?
80-
*/
81-
async shutdown(): Promise<void> {
82-
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#shutdown
83-
84-
if (this._shutdown) {
85-
api.diag.warn('shutdown may only be called once per MeterProvider');
86-
return;
87-
}
88-
89-
// TODO add a timeout - spec leaves it up the the SDK if this is configurable
90-
this._shutdown = true;
91-
92-
// Shut down all exporters and readers.
93-
// Log all Errors.
94-
for (const exporter of this._metricExporters) {
95-
try {
96-
await exporter.shutdown();
97-
} catch (e) {
98-
if (e instanceof Error) {
99-
api.diag.error(`Error shutting down: ${e.message}`)
100-
}
101-
}
125+
for (const exporter of [...this._metricExporters, ...this._metricReaders]) {
126+
try {
127+
await exporter.forceFlush();
128+
} catch (e) {
129+
if (e instanceof Error) {
130+
api.diag.error(`Error flushing: ${e.message}`)
102131
}
132+
}
103133
}
134+
}
135+
136+
public aggregate(_meter: Meter, _metric: unknown, _measurement: Measurement) {
137+
// TODO actually aggregate
104138

105139
/**
106-
* Notifies all exporters and metric readers to flush any buffered data.
107-
* Returns a promise which is resolved when all flushes are complete.
108-
*
109-
* TODO: return errors to caller somehow?
140+
* if there are no views:
141+
* apply the default configuration
142+
* else:
143+
* for each view:
144+
* if view matches:
145+
* apply view configuration
146+
* if no view matched:
147+
* if user has not disabled default fallback:
148+
* apply default configuration
110149
*/
111-
async forceFlush(): Promise<void> {
112-
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#forceflush
113-
114-
// TODO add a timeout - spec leaves it up the the SDK if this is configurable
115-
116-
// do not flush after shutdown
117-
if (this._shutdown) {
118-
api.diag.warn('invalid attempt to force flush after shutdown')
119-
return;
120-
}
121-
122-
for (const exporter of [...this._metricExporters, ...this._metricReaders]) {
123-
try {
124-
await exporter.forceFlush();
125-
} catch (e) {
126-
if (e instanceof Error) {
127-
api.diag.error(`Error flushing: ${e.message}`)
128-
}
129-
}
130-
}
131-
}
132-
133-
public aggregate(_meter: Meter, _metric: unknown, _measurement: Measurement) {
134-
// TODO actually aggregate
135-
136-
/**
137-
* if there are no views:
138-
* apply the default configuration
139-
* else:
140-
* for each view:
141-
* if view matches:
142-
* apply view configuration
143-
* if no view matched:
144-
* if user has not disabled default fallback:
145-
* apply default configuration
146-
*/
147-
}
150+
}
148151
}

experimental/packages/opentelemetry-sdk-metrics-base/src/View.ts

Lines changed: 0 additions & 113 deletions
This file was deleted.

0 commit comments

Comments
 (0)