From be48a8cada2e7a524aea6544c7db409242901bc6 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Fri, 20 Feb 2026 17:00:51 +0900 Subject: [PATCH 1/7] feat(sdk-logs): implement log creation metrics --- .../opentelemetry-sdk-node/src/sdk.ts | 12 +++-- .../opentelemetry-sdk-node/test/sdk.test.ts | 23 +++++++- experimental/packages/sdk-logs/package.json | 1 + experimental/packages/sdk-logs/src/Logger.ts | 1 + .../packages/sdk-logs/src/LoggerMetrics.ts | 36 +++++++++++++ .../packages/sdk-logs/src/LoggerProvider.ts | 4 +- .../src/internal/LoggerProviderSharedState.ts | 12 ++++- experimental/packages/sdk-logs/src/semconv.ts | 28 ++++++++++ experimental/packages/sdk-logs/src/types.ts | 7 +++ .../test/common/LoggerProvider.test.ts | 37 +++++++++++++ .../packages/sdk-logs/test/common/utils.ts | 11 ++++ .../packages/sdk-logs/tsconfig.esm.json | 3 ++ .../packages/sdk-logs/tsconfig.esnext.json | 3 ++ experimental/packages/sdk-logs/tsconfig.json | 3 ++ package-lock.json | 52 +++++++++++++++++++ 15 files changed, 224 insertions(+), 9 deletions(-) create mode 100644 experimental/packages/sdk-logs/src/LoggerMetrics.ts create mode 100644 experimental/packages/sdk-logs/src/semconv.ts diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index 26595cdcb6c..ec1a571531d 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -326,6 +326,12 @@ export class NodeSDK { }) ); + // While SDK metrics are unstable, we require an opt-in. + // https://opentelemetry.io/docs/specs/semconv/otel/sdk-metrics/ + const sdkMetricsEnabled = getBooleanFromEnv( + 'OTEL_NODE_EXPERIMENTAL_SDK_METRICS' + ); + if ( this._meterProviderConfig?.readers && // only register if there is a reader, otherwise we waste compute/memory. @@ -354,11 +360,6 @@ export class NodeSDK { // Only register if there is a span processor if (spanProcessors.length > 0) { - // While SDK metrics are unstable, we require an opt-in. - // https://opentelemetry.io/docs/specs/semconv/otel/sdk-metrics/ - const sdkMetricsEnabled = getBooleanFromEnv( - 'OTEL_NODE_EXPERIMENTAL_SDK_METRICS' - ); this._tracerProvider = new NodeTracerProvider({ ...this._configuration, resource: this._resource, @@ -373,6 +374,7 @@ export class NodeSDK { ...getLoggerProviderConfigFromEnv(), resource: this._resource, processors: this._loggerProviderConfig.logRecordProcessors, + meterProvider: sdkMetricsEnabled ? this._meterProvider : undefined, }); this._loggerProvider = loggerProvider; diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index c20320ad1cd..6aa7512f9c7 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -80,6 +80,7 @@ import { OTLPTraceExporter as OTLPProtoTraceExporter } from '@opentelemetry/expo import { OTLPTraceExporter as OTLPGrpcTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'; import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; +import { NOOP_COUNTER_METRIC } from '../../../../api/src/metrics/NoopMeter'; import { ATTR_HOST_NAME, ATTR_PROCESS_PID } from '../src/semconv'; function assertDefaultContextManagerRegistered() { @@ -420,7 +421,7 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should register a meter provider to the tracer provider if both initialized and metrics enabled', async () => { + it('should register a meter provider to the tracer and logger provider if all initialized and metrics enabled', async () => { process.env.OTEL_NODE_EXPERIMENTAL_SDK_METRICS = 'true'; const exporter = new ConsoleMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ @@ -432,6 +433,9 @@ describe('Node SDK', () => { const sdk = new NodeSDK({ metricReader: metricReader, traceExporter: new ConsoleSpanExporter(), + logRecordProcessor: new SimpleLogRecordProcessor( + new InMemoryLogRecordExporter() + ), autoDetectResources: false, }); @@ -447,12 +451,18 @@ describe('Node SDK', () => { (tracerProvider as any)._config.meterProvider instanceof MeterProvider ); + const loggerProvider = setGlobalLoggerProviderSpy.lastCall.args[0]; + assert.notDeepEqual( + (loggerProvider as any)['_sharedState'].loggerMetrics.createdLogs, + NOOP_COUNTER_METRIC + ); + assert.ok(metrics.getMeterProvider() instanceof MeterProvider); await sdk.shutdown(); }); - it('should not register a meter provider to the tracer provider if both initialized but metrics disabled', async () => { + it('should not register a meter provider to the tracer and logger provider if all initialized but metrics disabled', async () => { const exporter = new ConsoleMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ exporter: exporter, @@ -463,6 +473,9 @@ describe('Node SDK', () => { const sdk = new NodeSDK({ metricReader: metricReader, traceExporter: new ConsoleSpanExporter(), + logRecordProcessor: new SimpleLogRecordProcessor( + new InMemoryLogRecordExporter() + ), autoDetectResources: false, }); @@ -476,6 +489,12 @@ describe('Node SDK', () => { assert.ok(tracerProvider instanceof NodeTracerProvider); assert.equal((tracerProvider as any)._config.meterProvider, undefined); + const loggerProvider = setGlobalLoggerProviderSpy.lastCall.args[0]; + assert.deepEqual( + (loggerProvider as any)['_sharedState'].loggerMetrics.createdLogs, + NOOP_COUNTER_METRIC + ); + assert.ok(metrics.getMeterProvider() instanceof MeterProvider); await sdk.shutdown(); diff --git a/experimental/packages/sdk-logs/package.json b/experimental/packages/sdk-logs/package.json index dac8041a329..17a81793570 100644 --- a/experimental/packages/sdk-logs/package.json +++ b/experimental/packages/sdk-logs/package.json @@ -73,6 +73,7 @@ "@babel/core": "7.27.1", "@babel/preset-env": "7.27.2", "@opentelemetry/api": ">=1.4.0 <1.10.0", + "@opentelemetry/sdk-metrics": "2.2.0", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/sinon": "17.0.4", diff --git a/experimental/packages/sdk-logs/src/Logger.ts b/experimental/packages/sdk-logs/src/Logger.ts index 08e9b950ea0..6c7c2f2beef 100644 --- a/experimental/packages/sdk-logs/src/Logger.ts +++ b/experimental/packages/sdk-logs/src/Logger.ts @@ -97,6 +97,7 @@ export class Logger implements logsAPI.Logger { ...logRecord, } ); + this._sharedState.loggerMetrics.emitLog(); /** * the explicitly passed Context, * the current Context, or an empty Context if the Logger was obtained with include_trace_context=false diff --git a/experimental/packages/sdk-logs/src/LoggerMetrics.ts b/experimental/packages/sdk-logs/src/LoggerMetrics.ts new file mode 100644 index 00000000000..5136deaf041 --- /dev/null +++ b/experimental/packages/sdk-logs/src/LoggerMetrics.ts @@ -0,0 +1,36 @@ +/* + * 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 { Counter, Meter } from '@opentelemetry/api'; +import { METRIC_OTEL_SDK_LOG_CREATED } from './semconv'; + +/** + * Generates `otel.sdk.log.*` metrics. + * https://opentelemetry.io/docs/specs/semconv/otel/sdk-metrics/#log-metrics + */ +export class LoggerMetrics { + private readonly createdLogs: Counter; + + constructor(meter: Meter) { + this.createdLogs = meter.createCounter(METRIC_OTEL_SDK_LOG_CREATED, { + unit: '{log_record}', + description: 'The number of logs submitted to enabled SDK Loggers.', + }); + } + + emitLog() { + this.createdLogs.add(1); + } +} diff --git a/experimental/packages/sdk-logs/src/LoggerProvider.ts b/experimental/packages/sdk-logs/src/LoggerProvider.ts index 0da61e8d967..49aea67b6b9 100644 --- a/experimental/packages/sdk-logs/src/LoggerProvider.ts +++ b/experimental/packages/sdk-logs/src/LoggerProvider.ts @@ -44,13 +44,15 @@ export class LoggerProvider implements logsAPI.LoggerProvider { loggerConfigurator: config.loggerConfigurator ?? DEFAULT_LOGGER_CONFIGURATOR, processors: config.processors ?? [], + meterProvider: config.meterProvider, }; this._sharedState = new LoggerProviderSharedState( mergedConfig.resource, mergedConfig.forceFlushTimeoutMillis, mergedConfig.logRecordLimits, mergedConfig.processors, - mergedConfig.loggerConfigurator + mergedConfig.loggerConfigurator, + mergedConfig.meterProvider ); this._shutdownOnce = new BindOnceFuture(this._shutdown, this); } diff --git a/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts b/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts index 3d44594ea11..56489a15f76 100644 --- a/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts +++ b/experimental/packages/sdk-logs/src/internal/LoggerProviderSharedState.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { MeterProvider, createNoopMeter } from '@opentelemetry/api'; import { Logger } from '@opentelemetry/api-logs'; import { SeverityNumber } from '@opentelemetry/api-logs'; import { Resource } from '@opentelemetry/resources'; @@ -23,6 +24,8 @@ import { LogRecordLimits, LoggerConfig, LoggerConfigurator } from '../types'; import { NoopLogRecordProcessor } from '../export/NoopLogRecordProcessor'; import { MultiLogRecordProcessor } from '../MultiLogRecordProcessor'; import { getInstrumentationScopeKey } from './utils'; +import { LoggerMetrics } from '../LoggerMetrics'; +import { VERSION } from '../version'; const DEFAULT_LOGGER_CONFIG: Required = { disabled: false, @@ -45,6 +48,7 @@ export class LoggerProviderSharedState { readonly forceFlushTimeoutMillis: number; readonly logRecordLimits: Required; readonly processors: LogRecordProcessor[]; + readonly loggerMetrics: LoggerMetrics; private _loggerConfigurator: LoggerConfigurator; private _loggerConfigs: Map> = new Map(); @@ -53,7 +57,8 @@ export class LoggerProviderSharedState { forceFlushTimeoutMillis: number, logRecordLimits: Required, processors: LogRecordProcessor[], - loggerConfigurator?: LoggerConfigurator + loggerConfigurator?: LoggerConfigurator, + meterProvider?: MeterProvider ) { this.resource = resource; this.forceFlushTimeoutMillis = forceFlushTimeoutMillis; @@ -71,6 +76,11 @@ export class LoggerProviderSharedState { this._loggerConfigurator = loggerConfigurator ?? DEFAULT_LOGGER_CONFIGURATOR; + + const meter = meterProvider + ? meterProvider.getMeter('@opentelemetry/sdk-logs', VERSION) + : createNoopMeter(); + this.loggerMetrics = new LoggerMetrics(meter); } /** diff --git a/experimental/packages/sdk-logs/src/semconv.ts b/experimental/packages/sdk-logs/src/semconv.ts new file mode 100644 index 00000000000..b4e7d708d24 --- /dev/null +++ b/experimental/packages/sdk-logs/src/semconv.ts @@ -0,0 +1,28 @@ +/* + * 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. + */ + +/* + * This file contains a copy of unstable semantic convention definitions + * used by this package. + * @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv + */ + +/** + * The number of logs submitted to enabled SDK Loggers. + * + * @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const METRIC_OTEL_SDK_LOG_CREATED = 'otel.sdk.log.created' as const; diff --git a/experimental/packages/sdk-logs/src/types.ts b/experimental/packages/sdk-logs/src/types.ts index 044aab8314c..7ff0310960d 100644 --- a/experimental/packages/sdk-logs/src/types.ts +++ b/experimental/packages/sdk-logs/src/types.ts @@ -18,6 +18,7 @@ import type { Resource } from '@opentelemetry/resources'; import type { SeverityNumber } from '@opentelemetry/api-logs'; import type { InstrumentationScope } from '@opentelemetry/core'; import { LogRecordProcessor } from './LogRecordProcessor'; +import { MeterProvider } from '@opentelemetry/api'; /** * A LoggerConfig defines various configurable aspects of a Logger's behavior. @@ -94,6 +95,12 @@ export interface LoggerProviderConfig { * @experimental This feature is in development as per the OpenTelemetry specification. */ loggerConfigurator?: LoggerConfigurator; + + /** + * A meter provider to record logs SDK metrics to. + * @experimental This option is experimental and is subject to breaking changes in minor releases. + */ + meterProvider?: MeterProvider; } export interface LogRecordLimits { diff --git a/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts b/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts index 61a73600d8f..e41d337c116 100644 --- a/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts +++ b/experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts @@ -19,6 +19,7 @@ import { defaultResource, resourceFromAttributes, } from '@opentelemetry/resources'; +import { MeterProvider } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; import * as sinon from 'sinon'; @@ -27,6 +28,7 @@ import { NoopLogRecordProcessor } from '../../src/export/NoopLogRecordProcessor' import { DEFAULT_LOGGER_NAME } from './../../src/LoggerProvider'; import { MultiLogRecordProcessor } from '../../src/MultiLogRecordProcessor'; import { Logger } from '../../src/Logger'; +import { TestMetricReader } from './utils'; describe('LoggerProvider', () => { beforeEach(() => { @@ -314,4 +316,39 @@ describe('LoggerProvider', () => { sinon.assert.calledOnce(warnStub); }); }); + + describe('LoggerMetrics', () => { + it('should record metrics for created logs', async () => { + const metricReader = new TestMetricReader(); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); + + const logRecordProcessor = new NoopLogRecordProcessor(); + const provider = new LoggerProvider({ + processors: [logRecordProcessor], + meterProvider, + }); + const logger = provider.getLogger('test'); + logger.emit({ body: 'log 1' }); + let { resourceMetrics } = await metricReader.collect(); + let metrics = resourceMetrics.scopeMetrics[0].metrics; + let logsCreatedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.log.created' + ); + assert.ok(logsCreatedMetric); + assert.strictEqual(logsCreatedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(logsCreatedMetric.dataPoints[0].attributes, {}); + + logger.emit({ body: 'log 1' }); + ({ resourceMetrics } = await metricReader.collect()); + metrics = resourceMetrics.scopeMetrics[0].metrics; + logsCreatedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.log.created' + ); + assert.ok(logsCreatedMetric); + assert.strictEqual(logsCreatedMetric.dataPoints[0].value, 2); + assert.deepStrictEqual(logsCreatedMetric.dataPoints[0].attributes, {}); + }); + }); }); diff --git a/experimental/packages/sdk-logs/test/common/utils.ts b/experimental/packages/sdk-logs/test/common/utils.ts index 8363bd70b67..4c4bb5550cf 100644 --- a/experimental/packages/sdk-logs/test/common/utils.ts +++ b/experimental/packages/sdk-logs/test/common/utils.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { MetricReader } from '@opentelemetry/sdk-metrics'; + export const validAttributes = { string: 'string', number: 0, @@ -30,3 +32,12 @@ export const invalidAttributes = { // This empty length attribute should not be set '': 'empty-key', }; + +export class TestMetricReader extends MetricReader { + protected override onShutdown(): Promise { + return Promise.resolve(); + } + protected override onForceFlush(): Promise { + return Promise.resolve(); + } +} diff --git a/experimental/packages/sdk-logs/tsconfig.esm.json b/experimental/packages/sdk-logs/tsconfig.esm.json index 131e715221e..e535b844319 100644 --- a/experimental/packages/sdk-logs/tsconfig.esm.json +++ b/experimental/packages/sdk-logs/tsconfig.esm.json @@ -23,6 +23,9 @@ { "path": "../../../packages/opentelemetry-resources" }, + { + "path": "../../../packages/sdk-metrics" + }, { "path": "../../../semantic-conventions" }, diff --git a/experimental/packages/sdk-logs/tsconfig.esnext.json b/experimental/packages/sdk-logs/tsconfig.esnext.json index 52e36313312..57d99c99191 100644 --- a/experimental/packages/sdk-logs/tsconfig.esnext.json +++ b/experimental/packages/sdk-logs/tsconfig.esnext.json @@ -23,6 +23,9 @@ { "path": "../../../packages/opentelemetry-resources" }, + { + "path": "../../../packages/sdk-metrics" + }, { "path": "../../../semantic-conventions" }, diff --git a/experimental/packages/sdk-logs/tsconfig.json b/experimental/packages/sdk-logs/tsconfig.json index 392e6603dcf..5e0a3328d09 100644 --- a/experimental/packages/sdk-logs/tsconfig.json +++ b/experimental/packages/sdk-logs/tsconfig.json @@ -23,6 +23,9 @@ { "path": "../../../packages/opentelemetry-resources" }, + { + "path": "../../../packages/sdk-metrics" + }, { "path": "../../../semantic-conventions" }, diff --git a/package-lock.json b/package-lock.json index 4a329d4df0f..84a451d24b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1276,6 +1276,7 @@ "@babel/core": "7.27.1", "@babel/preset-env": "7.27.2", "@opentelemetry/api": ">=1.4.0 <1.10.0", + "@opentelemetry/sdk-metrics": "2.2.0", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/sinon": "17.0.4", @@ -1301,6 +1302,56 @@ "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, + "experimental/packages/sdk-logs/node_modules/@opentelemetry/sdk-metrics": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.2.0.tgz", + "integrity": "sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "experimental/packages/sdk-logs/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "experimental/packages/sdk-logs/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz", + "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, "experimental/packages/shim-opencensus": { "name": "@opentelemetry/shim-opencensus", "version": "0.212.0", @@ -6311,6 +6362,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">=14" } From fe17ddaa12c7019de8f42b485ffb783e5f6c0101 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Fri, 20 Feb 2026 17:02:52 +0900 Subject: [PATCH 2/7] Changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f7643203fa..e9788fdaef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,8 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :rocket: Features -* feat(sdk-trace): implement span start/end metrics [#1851](https://github.com/open-telemetry/opentelemetry-js/pull/6213) @anuraaga +* feat(sdk-logs): implement log creation metrics [#6433](https://github.com/open-telemetry/opentelemetry-js/pull/6433) @anuraaga +* feat(sdk-trace): implement span start/end metrics [#6213](https://github.com/open-telemetry/opentelemetry-js/pull/6213) @anuraaga ### :bug: Bug Fixes From 50cb8aa2f0e93179fbafbe8b73eff84ed0173702 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Thu, 26 Feb 2026 15:24:00 +0900 Subject: [PATCH 3/7] Simplify test name --- experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index 6aa7512f9c7..c6592cedcf1 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -421,7 +421,7 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should register a meter provider to the tracer and logger provider if all initialized and metrics enabled', async () => { + it('should configure components for metrics if enabled', async () => { process.env.OTEL_NODE_EXPERIMENTAL_SDK_METRICS = 'true'; const exporter = new ConsoleMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ @@ -462,7 +462,7 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should not register a meter provider to the tracer and logger provider if all initialized but metrics disabled', async () => { + it('should not configure components for metrics if disabled', async () => { const exporter = new ConsoleMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ exporter: exporter, From 1453e5e32d62cbf6a69bfceb6304f37d73a44250 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Thu, 5 Mar 2026 11:21:16 +0900 Subject: [PATCH 4/7] Cleanup --- .../opentelemetry-sdk-node/test/sdk.test.ts | 16 ++++++++-------- .../packages/sdk-logs/src/LoggerMetrics.ts | 13 +------------ experimental/packages/sdk-logs/src/semconv.ts | 13 +------------ 3 files changed, 10 insertions(+), 32 deletions(-) diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index e9d3cbc1400..212a2a5ef78 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -409,7 +409,7 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should configure components for metrics if enabled', async () => { + it('should configure components for SDK metrics if enabled', async () => { process.env.OTEL_NODE_EXPERIMENTAL_SDK_METRICS = 'true'; const exporter = new ConsoleMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ @@ -421,9 +421,9 @@ describe('Node SDK', () => { const sdk = new NodeSDK({ metricReader: metricReader, traceExporter: new ConsoleSpanExporter(), - logRecordProcessor: new SimpleLogRecordProcessor( - new InMemoryLogRecordExporter() - ), + logRecordProcessors: [ + new SimpleLogRecordProcessor(new InMemoryLogRecordExporter()), + ], autoDetectResources: false, }); @@ -450,7 +450,7 @@ describe('Node SDK', () => { await sdk.shutdown(); }); - it('should not configure components for metrics if disabled', async () => { + it('should not configure components for SDK metrics if disabled', async () => { const exporter = new ConsoleMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ exporter: exporter, @@ -461,9 +461,9 @@ describe('Node SDK', () => { const sdk = new NodeSDK({ metricReader: metricReader, traceExporter: new ConsoleSpanExporter(), - logRecordProcessor: new SimpleLogRecordProcessor( - new InMemoryLogRecordExporter() - ), + logRecordProcessors: [ + new SimpleLogRecordProcessor(new InMemoryLogRecordExporter()), + ], autoDetectResources: false, }); diff --git a/experimental/packages/sdk-logs/src/LoggerMetrics.ts b/experimental/packages/sdk-logs/src/LoggerMetrics.ts index 5136deaf041..33b5f66add5 100644 --- a/experimental/packages/sdk-logs/src/LoggerMetrics.ts +++ b/experimental/packages/sdk-logs/src/LoggerMetrics.ts @@ -1,17 +1,6 @@ /* * 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. + * SPDX-License-Identifier: Apache-2.0 */ import { Counter, Meter } from '@opentelemetry/api'; import { METRIC_OTEL_SDK_LOG_CREATED } from './semconv'; diff --git a/experimental/packages/sdk-logs/src/semconv.ts b/experimental/packages/sdk-logs/src/semconv.ts index b4e7d708d24..80a4462e6d3 100644 --- a/experimental/packages/sdk-logs/src/semconv.ts +++ b/experimental/packages/sdk-logs/src/semconv.ts @@ -1,17 +1,6 @@ /* * 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. + * SPDX-License-Identifier: Apache-2.0 */ /* From 7028ee29e48e9116d6552f856955d75d96aad58b Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Thu, 5 Mar 2026 11:22:22 +0900 Subject: [PATCH 5/7] package-lock --- experimental/packages/sdk-logs/package.json | 2 +- package-lock.json | 65 +-------------------- 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/experimental/packages/sdk-logs/package.json b/experimental/packages/sdk-logs/package.json index 9c0eb72be2a..07dbf4d25c5 100644 --- a/experimental/packages/sdk-logs/package.json +++ b/experimental/packages/sdk-logs/package.json @@ -73,7 +73,7 @@ "@babel/core": "7.27.1", "@babel/preset-env": "7.27.2", "@opentelemetry/api": ">=1.4.0 <1.10.0", - "@opentelemetry/sdk-metrics": "2.2.0", + "@opentelemetry/sdk-metrics": "2.6.0", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/sinon": "17.0.4", diff --git a/package-lock.json b/package-lock.json index d05b4e5b272..66b29f91d78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1276,7 +1276,7 @@ "@babel/core": "7.27.1", "@babel/preset-env": "7.27.2", "@opentelemetry/api": ">=1.4.0 <1.10.0", - "@opentelemetry/sdk-metrics": "2.2.0", + "@opentelemetry/sdk-metrics": "2.6.0", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/sinon": "17.0.4", @@ -1302,56 +1302,6 @@ "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, - "experimental/packages/sdk-logs/node_modules/@opentelemetry/sdk-metrics": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.2.0.tgz", - "integrity": "sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.2.0", - "@opentelemetry/resources": "2.2.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.9.0 <1.10.0" - } - }, - "experimental/packages/sdk-logs/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", - "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "experimental/packages/sdk-logs/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz", - "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.2.0", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" - } - }, "experimental/packages/shim-opencensus": { "name": "@opentelemetry/shim-opencensus", "version": "0.213.0", @@ -5748,9 +5698,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5765,9 +5712,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5782,9 +5726,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5799,9 +5740,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6459,7 +6397,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=14" } From 1c9cde2e1d6565ee760a85aed5ff727647cea155 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Thu, 5 Mar 2026 11:45:25 +0900 Subject: [PATCH 6/7] Lint --- experimental/packages/sdk-logs/src/LoggerMetrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/packages/sdk-logs/src/LoggerMetrics.ts b/experimental/packages/sdk-logs/src/LoggerMetrics.ts index 33b5f66add5..6f7b4419e6d 100644 --- a/experimental/packages/sdk-logs/src/LoggerMetrics.ts +++ b/experimental/packages/sdk-logs/src/LoggerMetrics.ts @@ -2,7 +2,7 @@ * Copyright The OpenTelemetry Authors * SPDX-License-Identifier: Apache-2.0 */ -import { Counter, Meter } from '@opentelemetry/api'; +import type { Counter, Meter } from '@opentelemetry/api'; import { METRIC_OTEL_SDK_LOG_CREATED } from './semconv'; /** From 0937288af728637132ae2d2e14207821dd54fa18 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Thu, 2 Apr 2026 12:05:22 +0900 Subject: [PATCH 7/7] Updates --- CHANGELOG.md | 3 ++- experimental/packages/sdk-logs/package.json | 2 +- package-lock.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 264b5ddf6a1..3fa84fc7856 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :rocket: Features +* feat(sdk-logs): implement log creation metrics [#6433](https://github.com/open-telemetry/opentelemetry-js/pull/6433) @anuraaga + ### :bug: Bug Fixes ### :books: Documentation @@ -47,7 +49,6 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :rocket: Features -* feat(sdk-logs): implement log creation metrics [#6433](https://github.com/open-telemetry/opentelemetry-js/pull/6433) @anuraaga * feat(sdk-trace): implement span start/end metrics [#6213](https://github.com/open-telemetry/opentelemetry-js/pull/6213) @anuraaga ### :bug: Bug Fixes diff --git a/experimental/packages/sdk-logs/package.json b/experimental/packages/sdk-logs/package.json index 8d7d255d856..33b9fdb0fdc 100644 --- a/experimental/packages/sdk-logs/package.json +++ b/experimental/packages/sdk-logs/package.json @@ -73,7 +73,7 @@ "@babel/core": "7.27.1", "@babel/preset-env": "7.27.2", "@opentelemetry/api": ">=1.4.0 <1.10.0", - "@opentelemetry/sdk-metrics": "2.6.0", + "@opentelemetry/sdk-metrics": "2.6.1", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/sinon": "17.0.4", diff --git a/package-lock.json b/package-lock.json index b67119ac908..1f78451e8d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1185,7 +1185,7 @@ "@babel/core": "7.27.1", "@babel/preset-env": "7.27.2", "@opentelemetry/api": ">=1.4.0 <1.10.0", - "@opentelemetry/sdk-metrics": "2.6.0", + "@opentelemetry/sdk-metrics": "2.6.1", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/sinon": "17.0.4",