Skip to content

Commit

Permalink
fix(sdk-node): update instrumentations once MeterProvider is initiali…
Browse files Browse the repository at this point in the history
…zed (#3624)

* fix(sdk-node): provide workaround for broken metrics instrumentation registration

* fix(changelog): add changelog entry

---------

Co-authored-by: Daniel Dyla <dyladan@users.noreply.github.com>
  • Loading branch information
pichlermarc and dyladan authored Mar 2, 2023
1 parent 4a4484a commit cbbdfd3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ All notable changes to experimental packages in this project will be documented
### :bug: (Bug Fix)

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

### :books: (Refine Doc)

Expand Down
11 changes: 11 additions & 0 deletions experimental/packages/opentelemetry-sdk-node/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { NodeSDKConfiguration } from './types';
import { TracerProviderWithEnvExporters } from './TracerProviderWithEnvExporter';
import { getEnv } from '@opentelemetry/core';
import { parseInstrumentationOptions } from './utils';

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

Expand All @@ -61,6 +62,7 @@ export type MeterProviderConfig = {
*/
views?: View[];
};

export class NodeSDK {
private _tracerProviderConfig?: {
tracerConfig: NodeTracerConfig;
Expand Down Expand Up @@ -275,6 +277,15 @@ export class NodeSDK {
this._meterProvider = meterProvider;

metrics.setGlobalMeterProvider(meterProvider);

// TODO: This is a workaround to fix https://github.com/open-telemetry/opentelemetry-js/issues/3609
// If the MeterProvider is not yet registered when instrumentations are registered, all metrics are dropped.
// This code is obsolete once https://github.com/open-telemetry/opentelemetry-js/issues/3622 is implemented.
for (const instrumentation of parseInstrumentationOptions(
this._instrumentations
)) {
instrumentation.setMeterProvider(metrics.getMeterProvider());
}
}
}

Expand Down
43 changes: 43 additions & 0 deletions experimental/packages/opentelemetry-sdk-node/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {
Instrumentation,
InstrumentationOption,
} from '@opentelemetry/instrumentation';

// TODO: This part of a workaround to fix https://github.com/open-telemetry/opentelemetry-js/issues/3609
// If the MeterProvider is not yet registered when instrumentations are registered, all metrics are dropped.
// This code is obsolete once https://github.com/open-telemetry/opentelemetry-js/issues/3622 is implemented.
export function parseInstrumentationOptions(
options: InstrumentationOption[] = []
): Instrumentation[] {
let instrumentations: Instrumentation[] = [];
for (let i = 0, j = options.length; i < j; i++) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const option = options[i] as any;
if (Array.isArray(option)) {
const results = parseInstrumentationOptions(option);
instrumentations = instrumentations.concat(results);
} else if (typeof option === 'function') {
instrumentations.push(new option());
} else if ((option as Instrumentation).instrumentationName) {
instrumentations.push(option);
}
}

return instrumentations;
}

0 comments on commit cbbdfd3

Please sign in to comment.