Skip to content

Commit cbbdfd3

Browse files
pichlermarcdyladan
andauthored
fix(sdk-node): update instrumentations once MeterProvider is initialized (#3624)
* fix(sdk-node): provide workaround for broken metrics instrumentation registration * fix(changelog): add changelog entry --------- Co-authored-by: Daniel Dyla <[email protected]>
1 parent 4a4484a commit cbbdfd3

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

experimental/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ All notable changes to experimental packages in this project will be documented
1919
### :bug: (Bug Fix)
2020

2121
* fix(prometheus-exporter): add possibility to respond to errors returned by `server.listen()` [#3552](https://github.com/open-telemetry/opentelemetry-js/pull/3402) @pichlermarc
22+
fix(sdk-node): update instrumentations once MeterProvider is initialized [#3624](https://github.com/open-telemetry/opentelemetry-js/pull/3624) @pichlermarc
2223

2324
### :books: (Refine Doc)
2425

experimental/packages/opentelemetry-sdk-node/src/sdk.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
4848
import { NodeSDKConfiguration } from './types';
4949
import { TracerProviderWithEnvExporters } from './TracerProviderWithEnvExporter';
5050
import { getEnv } from '@opentelemetry/core';
51+
import { parseInstrumentationOptions } from './utils';
5152

5253
/** This class represents everything needed to register a fully configured OpenTelemetry Node.js SDK */
5354

@@ -61,6 +62,7 @@ export type MeterProviderConfig = {
6162
*/
6263
views?: View[];
6364
};
65+
6466
export class NodeSDK {
6567
private _tracerProviderConfig?: {
6668
tracerConfig: NodeTracerConfig;
@@ -275,6 +277,15 @@ export class NodeSDK {
275277
this._meterProvider = meterProvider;
276278

277279
metrics.setGlobalMeterProvider(meterProvider);
280+
281+
// TODO: This is a workaround to fix https://github.com/open-telemetry/opentelemetry-js/issues/3609
282+
// If the MeterProvider is not yet registered when instrumentations are registered, all metrics are dropped.
283+
// This code is obsolete once https://github.com/open-telemetry/opentelemetry-js/issues/3622 is implemented.
284+
for (const instrumentation of parseInstrumentationOptions(
285+
this._instrumentations
286+
)) {
287+
instrumentation.setMeterProvider(metrics.getMeterProvider());
288+
}
278289
}
279290
}
280291

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import {
18+
Instrumentation,
19+
InstrumentationOption,
20+
} from '@opentelemetry/instrumentation';
21+
22+
// TODO: This part of a workaround to fix https://github.com/open-telemetry/opentelemetry-js/issues/3609
23+
// If the MeterProvider is not yet registered when instrumentations are registered, all metrics are dropped.
24+
// This code is obsolete once https://github.com/open-telemetry/opentelemetry-js/issues/3622 is implemented.
25+
export function parseInstrumentationOptions(
26+
options: InstrumentationOption[] = []
27+
): Instrumentation[] {
28+
let instrumentations: Instrumentation[] = [];
29+
for (let i = 0, j = options.length; i < j; i++) {
30+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
31+
const option = options[i] as any;
32+
if (Array.isArray(option)) {
33+
const results = parseInstrumentationOptions(option);
34+
instrumentations = instrumentations.concat(results);
35+
} else if (typeof option === 'function') {
36+
instrumentations.push(new option());
37+
} else if ((option as Instrumentation).instrumentationName) {
38+
instrumentations.push(option);
39+
}
40+
}
41+
42+
return instrumentations;
43+
}

0 commit comments

Comments
 (0)