From c0790f25ab269e43f68caac0f838bda08fbb2103 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 11 Feb 2025 16:45:28 +0100 Subject: [PATCH] refactor(auto-instrumentations-node): migrate away from getEnv() --- .../src/register.ts | 6 +-- .../auto-instrumentations-node/src/utils.ts | 26 ++++++++++- .../test/utils.test.ts | 44 ++++++++++++++++++- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/metapackages/auto-instrumentations-node/src/register.ts b/metapackages/auto-instrumentations-node/src/register.ts index d47556f061..3a4ae6cd5a 100644 --- a/metapackages/auto-instrumentations-node/src/register.ts +++ b/metapackages/auto-instrumentations-node/src/register.ts @@ -16,14 +16,12 @@ import * as opentelemetry from '@opentelemetry/sdk-node'; import { diag, DiagConsoleLogger } from '@opentelemetry/api'; import { + getLogLevelFromEnv, getNodeAutoInstrumentations, getResourceDetectorsFromEnv, } from './utils'; -diag.setLogger( - new DiagConsoleLogger(), - opentelemetry.core.getEnv().OTEL_LOG_LEVEL -); +diag.setLogger(new DiagConsoleLogger(), getLogLevelFromEnv()); const sdk = new opentelemetry.NodeSDK({ instrumentations: getNodeAutoInstrumentations(), diff --git a/metapackages/auto-instrumentations-node/src/utils.ts b/metapackages/auto-instrumentations-node/src/utils.ts index c8ffd50c27..787a97eb43 100644 --- a/metapackages/auto-instrumentations-node/src/utils.ts +++ b/metapackages/auto-instrumentations-node/src/utils.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; +import { diag, DiagLogLevel } from '@opentelemetry/api'; import { Instrumentation } from '@opentelemetry/instrumentation'; import { AmqplibInstrumentation } from '@opentelemetry/instrumentation-amqplib'; @@ -136,6 +136,17 @@ const InstrumentationMap = { '@opentelemetry/instrumentation-winston': WinstonInstrumentation, }; +// The support string -> DiagLogLevel mappings +const logLevelMap: { [key: string]: DiagLogLevel } = { + ALL: DiagLogLevel.ALL, + VERBOSE: DiagLogLevel.VERBOSE, + DEBUG: DiagLogLevel.DEBUG, + INFO: DiagLogLevel.INFO, + WARN: DiagLogLevel.WARN, + ERROR: DiagLogLevel.ERROR, + NONE: DiagLogLevel.NONE, +}; + const defaultExcludedInstrumentations = [ '@opentelemetry/instrumentation-fs', '@opentelemetry/instrumentation-fastify', @@ -293,3 +304,16 @@ export function getResourceDetectorsFromEnv(): Array { return resourceDetector || []; }); } + +export function getLogLevelFromEnv(): DiagLogLevel { + const rawLogLevel = process.env.OTEL_LOG_LEVEL; + + // NOTE: as per specification we should actually only register if something is set, but our previous implementation + // always registered a logger, even when nothing was set. Falling back to 'INFO' here to keep the same behavior as + // with previous implementations. + // Also: no point in warning - no logger is registered yet + return ( + logLevelMap[rawLogLevel?.trim().toUpperCase() ?? 'INFO'] ?? + DiagLogLevel.INFO + ); +} diff --git a/metapackages/auto-instrumentations-node/test/utils.test.ts b/metapackages/auto-instrumentations-node/test/utils.test.ts index 6be7ed6692..f3581b064d 100644 --- a/metapackages/auto-instrumentations-node/test/utils.test.ts +++ b/metapackages/auto-instrumentations-node/test/utils.test.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; +import { diag, DiagLogLevel } from '@opentelemetry/api'; import { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { getNodeAutoInstrumentations } from '../src'; -import { getResourceDetectorsFromEnv } from '../src/utils'; +import { getLogLevelFromEnv, getResourceDetectorsFromEnv } from '../src/utils'; describe('utils', () => { describe('getNodeAutoInstrumentations', () => { @@ -223,4 +223,44 @@ describe('utils', () => { delete process.env.OTEL_NODE_RESOURCE_DETECTORS; }); }); + + describe('getLogLevelFromEnv', function () { + afterEach(function () { + delete process.env.OTEL_LOG_LEVEL; + }); + + it('should select log level based on env var', function () { + process.env.OTEL_LOG_LEVEL = 'NONE'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.NONE); + process.env.OTEL_LOG_LEVEL = 'VERBOSE'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.VERBOSE); + process.env.OTEL_LOG_LEVEL = 'DEBUG'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.DEBUG); + process.env.OTEL_LOG_LEVEL = 'INFO'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.INFO); + process.env.OTEL_LOG_LEVEL = 'WARN'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.WARN); + process.env.OTEL_LOG_LEVEL = 'ERROR'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.ERROR); + process.env.OTEL_LOG_LEVEL = 'ALL'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.ALL); + }); + + it('should ignore casing', function () { + process.env.OTEL_LOG_LEVEL = 'warn'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.WARN); + process.env.OTEL_LOG_LEVEL = 'WaRN'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.WARN); + }); + + it('should fall back to INFO on bogus input', function () { + process.env.OTEL_LOG_LEVEL = 'bogus'; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.INFO); + }); + + it('should use INFO when unset', function () { + delete process.env.OTEL_LOG_LEVEL; + assert.strictEqual(getLogLevelFromEnv(), DiagLogLevel.INFO); + }); + }); });