From 0e5498698c0e906a29894c1ab5152816370bfdb3 Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:38:23 -0700 Subject: [PATCH 1/7] Add delegating no-op logger provider --- .../packages/api-logs/src/ProxyLogger.ts | 69 +++++++++++ .../api-logs/src/ProxyLoggerProvider.ts | 55 ++++++++ .../packages/api-logs/src/api/logs.ts | 7 +- experimental/packages/api-logs/src/index.ts | 2 + .../packages/api-logs/test/api/api.test.ts | 10 +- .../api-logs/test/internal/global.test.ts | 8 +- .../proxy-logger.test.ts | 117 ++++++++++++++++++ .../opentelemetry-sdk-node/test/sdk.test.ts | 18 ++- 8 files changed, 274 insertions(+), 12 deletions(-) create mode 100644 experimental/packages/api-logs/src/ProxyLogger.ts create mode 100644 experimental/packages/api-logs/src/ProxyLoggerProvider.ts create mode 100644 experimental/packages/api-logs/test/proxy-implementations/proxy-logger.test.ts diff --git a/experimental/packages/api-logs/src/ProxyLogger.ts b/experimental/packages/api-logs/src/ProxyLogger.ts new file mode 100644 index 0000000000..90d4a71ce7 --- /dev/null +++ b/experimental/packages/api-logs/src/ProxyLogger.ts @@ -0,0 +1,69 @@ +/* + * 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 { NOOP_LOGGER } from './NoopLogger'; +import { Logger } from './types/Logger'; +import { LoggerOptions } from './types/LoggerOptions'; +import { LogRecord } from './types/LogRecord'; + +export class ProxyLogger implements Logger { + // When a real implementation is provided, this will be it + private _delegate?: Logger; + + constructor( + private _provider: LoggerDelegator, + public readonly name: string, + public readonly version?: string | undefined, + public readonly options?: LoggerOptions | undefined + ) {} + + /** + * Emit a log record. This method should only be used by log appenders. + * + * @param logRecord + */ + emit(_logRecord: LogRecord): void { + this._getLogger().emit(_logRecord); + } + + /** + * Try to get a logger from the proxy logger provider. + * If the proxy logger provider has no delegate, return a noop logger. + */ + private _getLogger() { + if (this._delegate) { + return this._delegate; + } + const logger = this._provider.getDelegateLogger( + this.name, + this.version, + this.options + ); + if (!logger) { + return NOOP_LOGGER; + } + this._delegate = logger; + return this._delegate; + } +} + +export interface LoggerDelegator { + getDelegateLogger( + name: string, + version?: string, + options?: LoggerOptions + ): Logger | undefined; +} diff --git a/experimental/packages/api-logs/src/ProxyLoggerProvider.ts b/experimental/packages/api-logs/src/ProxyLoggerProvider.ts new file mode 100644 index 0000000000..731facf719 --- /dev/null +++ b/experimental/packages/api-logs/src/ProxyLoggerProvider.ts @@ -0,0 +1,55 @@ +/* + * 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 { LoggerProvider } from './types/LoggerProvider'; +import { Logger } from './types/Logger'; +import { LoggerOptions } from './types/LoggerOptions'; +import { NOOP_LOGGER_PROVIDER } from './NoopLoggerProvider'; +import { ProxyLogger } from './ProxyLogger'; + +export class ProxyLoggerProvider implements LoggerProvider { + private _delegate?: LoggerProvider; + + getLogger( + _name: string, + _version?: string | undefined, + _options?: LoggerOptions | undefined + ): Logger { + return ( + this.getDelegateLogger(_name, _version, _options) ?? + new ProxyLogger(this, _name, _version, _options) + ); + } + + getDelegate(): LoggerProvider { + return this._delegate ?? NOOP_LOGGER_PROVIDER; + } + + /** + * Set the delegate logger provider + */ + setDelegate(delegate: LoggerProvider) { + this._delegate = delegate; + } + + getDelegateLogger( + name: string, + version?: string | undefined, + options?: LoggerOptions | undefined + ): Logger | undefined { + return this._delegate?.getLogger(name, version, options); + } +} diff --git a/experimental/packages/api-logs/src/api/logs.ts b/experimental/packages/api-logs/src/api/logs.ts index d6f24b5e07..b4f5ab7aa9 100644 --- a/experimental/packages/api-logs/src/api/logs.ts +++ b/experimental/packages/api-logs/src/api/logs.ts @@ -24,10 +24,13 @@ import { LoggerProvider } from '../types/LoggerProvider'; import { NOOP_LOGGER_PROVIDER } from '../NoopLoggerProvider'; import { Logger } from '../types/Logger'; import { LoggerOptions } from '../types/LoggerOptions'; +import { ProxyLoggerProvider } from '../ProxyLoggerProvider'; export class LogsAPI { private static _instance?: LogsAPI; + private _proxyLoggerProvider = new ProxyLoggerProvider(); + private constructor() {} public static getInstance(): LogsAPI { @@ -48,6 +51,7 @@ export class LogsAPI { provider, NOOP_LOGGER_PROVIDER ); + this._proxyLoggerProvider.setDelegate(provider); return provider; } @@ -60,7 +64,7 @@ export class LogsAPI { public getLoggerProvider(): LoggerProvider { return ( _global[GLOBAL_LOGS_API_KEY]?.(API_BACKWARDS_COMPATIBILITY_VERSION) ?? - NOOP_LOGGER_PROVIDER + this._proxyLoggerProvider ); } @@ -80,5 +84,6 @@ export class LogsAPI { /** Remove the global logger provider */ public disable(): void { delete _global[GLOBAL_LOGS_API_KEY]; + this._proxyLoggerProvider = new ProxyLoggerProvider(); } } diff --git a/experimental/packages/api-logs/src/index.ts b/experimental/packages/api-logs/src/index.ts index 3ea2ae39c8..a5c017627f 100644 --- a/experimental/packages/api-logs/src/index.ts +++ b/experimental/packages/api-logs/src/index.ts @@ -21,6 +21,8 @@ export * from './types/LoggerOptions'; export * from './types/AnyValue'; export * from './NoopLogger'; export * from './NoopLoggerProvider'; +export * from './ProxyLogger'; +export * from './ProxyLoggerProvider'; import { LogsAPI } from './api/logs'; export const logs = LogsAPI.getInstance(); diff --git a/experimental/packages/api-logs/test/api/api.test.ts b/experimental/packages/api-logs/test/api/api.test.ts index 3548e08184..6994430420 100644 --- a/experimental/packages/api-logs/test/api/api.test.ts +++ b/experimental/packages/api-logs/test/api/api.test.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import { Logger, logs } from '../../src'; +import { Logger, ProxyLoggerProvider, logs } from '../../src'; import { NoopLogger } from '../../src/NoopLogger'; import { NoopLoggerProvider } from '../../src/NoopLoggerProvider'; @@ -23,9 +23,11 @@ describe('API', () => { const dummyLogger = new NoopLogger(); it('should expose a logger provider via getLoggerProvider', () => { - const provider = logs.getLoggerProvider(); - assert.ok(provider); - assert.strictEqual(typeof provider, 'object'); + assert.ok(logs.getLoggerProvider() instanceof ProxyLoggerProvider); + assert.ok( + (logs.getLoggerProvider() as ProxyLoggerProvider).getDelegate() instanceof + NoopLoggerProvider + ); }); describe('GlobalLoggerProvider', () => { diff --git a/experimental/packages/api-logs/test/internal/global.test.ts b/experimental/packages/api-logs/test/internal/global.test.ts index 8ac9c48cf3..da0fbdbb16 100644 --- a/experimental/packages/api-logs/test/internal/global.test.ts +++ b/experimental/packages/api-logs/test/internal/global.test.ts @@ -17,6 +17,7 @@ import * as assert from 'assert'; import { _global, GLOBAL_LOGS_API_KEY } from '../../src/internal/global-utils'; import { NoopLoggerProvider } from '../../src/NoopLoggerProvider'; +import { ProxyLoggerProvider } from '../../src'; const api1 = require('../../src') as typeof import('../../src'); @@ -66,11 +67,10 @@ describe('Global Utils', () => { assert.strictEqual(original, api1.logs.getLoggerProvider()); }); - it('should return the module NoOp implementation if the version is a mismatch', () => { - const original = api1.logs.getLoggerProvider(); - api1.logs.setGlobalLoggerProvider(new NoopLoggerProvider()); + it('should return the module no op implementation if the version is a mismatch', () => { + api1.logs.setGlobalLoggerProvider(new ProxyLoggerProvider()); const afterSet = _global[GLOBAL_LOGS_API_KEY]!(-1); - assert.strictEqual(original, afterSet); + assert.ok(afterSet instanceof NoopLoggerProvider); }); }); diff --git a/experimental/packages/api-logs/test/proxy-implementations/proxy-logger.test.ts b/experimental/packages/api-logs/test/proxy-implementations/proxy-logger.test.ts new file mode 100644 index 0000000000..85d9f593c0 --- /dev/null +++ b/experimental/packages/api-logs/test/proxy-implementations/proxy-logger.test.ts @@ -0,0 +1,117 @@ +/* + * 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 * as assert from 'assert'; +import * as sinon from 'sinon'; +import { + Logger, + LoggerProvider, + ProxyLogger, + ProxyLoggerProvider, +} from '../../src'; +import { NoopLogger } from '../../src/NoopLogger'; + +describe('ProxyLogger', () => { + let provider: ProxyLoggerProvider; + const sandbox = sinon.createSandbox(); + + beforeEach(() => { + provider = new ProxyLoggerProvider(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + describe('when no delegate is set', () => { + it('should return proxy loggers', () => { + const logger = provider.getLogger('test'); + assert.ok(logger instanceof ProxyLogger); + }); + }); + + describe('when delegate is set before getLogger', () => { + let delegate: LoggerProvider; + let getLoggerStub: sinon.SinonStub; + + beforeEach(() => { + getLoggerStub = sandbox.stub().returns(new NoopLogger()); + delegate = { + getLogger: getLoggerStub, + }; + provider.setDelegate(delegate); + }); + + it('should return loggers directly from the delegate', () => { + const logger = provider.getLogger('test', 'v0'); + + sandbox.assert.calledOnce(getLoggerStub); + assert.strictEqual(getLoggerStub.firstCall.returnValue, logger); + assert.deepStrictEqual(getLoggerStub.firstCall.args, [ + 'test', + 'v0', + undefined, + ]); + }); + + it('should return loggers directly from the delegate with schema url', () => { + const logger = provider.getLogger('test', 'v0', { + schemaUrl: 'https://opentelemetry.io/schemas/1.7.0', + }); + + sandbox.assert.calledOnce(getLoggerStub); + assert.strictEqual(getLoggerStub.firstCall.returnValue, logger); + assert.deepStrictEqual(getLoggerStub.firstCall.args, [ + 'test', + 'v0', + { schemaUrl: 'https://opentelemetry.io/schemas/1.7.0' }, + ]); + }); + }); + + describe('when delegate is set after getLogger', () => { + let logger: Logger; + let delegateProvider: LoggerProvider; + + let delegateLogger: Logger; + let emitCalled: boolean; + + beforeEach(() => { + emitCalled = false; + delegateLogger = { + emit() { + emitCalled = true; + }, + }; + + logger = provider.getLogger('test'); + + delegateProvider = { + getLogger() { + return delegateLogger; + }, + }; + provider.setDelegate(delegateProvider); + }); + + it('should emit from the delegate logger', () => { + logger.emit({ + body: 'Test', + }); + assert.ok(emitCalled); + }); + }); +}); diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index 22e1794ccc..d019e92a49 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -65,7 +65,7 @@ import { serviceInstanceIdDetectorSync, } from '@opentelemetry/resources'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; -import { logs } from '@opentelemetry/api-logs'; +import { logs, ProxyLoggerProvider } from '@opentelemetry/api-logs'; import { SimpleLogRecordProcessor, InMemoryLogRecordExporter, @@ -84,6 +84,7 @@ describe('Node SDK', () => { let ctxManager: any; let propagator: any; let delegate: any; + let logsDelegate: any; beforeEach(() => { diag.disable(); @@ -91,10 +92,14 @@ describe('Node SDK', () => { trace.disable(); propagation.disable(); metrics.disable(); + logs.disable(); ctxManager = context['_getContextManager'](); propagator = propagation['_getGlobalPropagator'](); delegate = (trace.getTracerProvider() as ProxyTracerProvider).getDelegate(); + logsDelegate = ( + logs.getLoggerProvider() as ProxyLoggerProvider + ).getDelegate(); }); afterEach(() => { @@ -128,7 +133,11 @@ describe('Node SDK', () => { 'tracer provider should not have changed' ); assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); - assert.ok(!(logs.getLoggerProvider() instanceof LoggerProvider)); + assert.strictEqual( + (logs.getLoggerProvider() as ProxyLoggerProvider).getDelegate(), + logsDelegate, + 'logger provider should not have changed' + ); delete env.OTEL_TRACES_EXPORTER; await sdk.shutdown(); }); @@ -321,7 +330,10 @@ describe('Node SDK', () => { 'tracer provider should not have changed' ); - assert.ok(logs.getLoggerProvider() instanceof LoggerProvider); + assert.ok( + (logs.getLoggerProvider() as ProxyLoggerProvider) instanceof + LoggerProvider + ); await sdk.shutdown(); delete env.OTEL_TRACES_EXPORTER; }); From cd6b14fc0b2af6e641d5e2ce8d77deb4bfed709a Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:46:02 -0700 Subject: [PATCH 2/7] Add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 644972b950..afd2ba6e89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/ ### :boom: Breaking Change +* feat(api): Add delegating no-op logger provider [#4861](https://github.com/open-telemetry/opentelemetry-js/pull/4861) @hectorhdzg + ### :rocket: (Enhancement) ### :bug: (Bug Fix) From ca01e0b0fec6ab4796a0869578eb24f8b3b720e6 Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Thu, 11 Jul 2024 17:19:34 -0700 Subject: [PATCH 3/7] Update experimental changelog --- CHANGELOG.md | 2 -- experimental/CHANGELOG.md | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afd2ba6e89..644972b950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,6 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/ ### :boom: Breaking Change -* feat(api): Add delegating no-op logger provider [#4861](https://github.com/open-telemetry/opentelemetry-js/pull/4861) @hectorhdzg - ### :rocket: (Enhancement) ### :bug: (Bug Fix) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 725578ab7a..8e16aa8c2c 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change * fix(instrumentation)!:remove unused description property from interface [#4847](https://github.com/open-telemetry/opentelemetry-js/pull/4847) @blumamir +* feat(api-logs): Add delegating no-op logger provider [#4861](https://github.com/open-telemetry/opentelemetry-js/pull/4861) @hectorhdzg ### :rocket: (Enhancement) From d26e908fc25a76d638ae93e73ca63ea6765b53cc Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:45:51 -0700 Subject: [PATCH 4/7] Address comments --- experimental/packages/api-logs/src/ProxyLogger.ts | 4 ++-- .../packages/api-logs/src/ProxyLoggerProvider.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/experimental/packages/api-logs/src/ProxyLogger.ts b/experimental/packages/api-logs/src/ProxyLogger.ts index 90d4a71ce7..7869c65eac 100644 --- a/experimental/packages/api-logs/src/ProxyLogger.ts +++ b/experimental/packages/api-logs/src/ProxyLogger.ts @@ -35,8 +35,8 @@ export class ProxyLogger implements Logger { * * @param logRecord */ - emit(_logRecord: LogRecord): void { - this._getLogger().emit(_logRecord); + emit(logRecord: LogRecord): void { + this._getLogger().emit(logRecord); } /** diff --git a/experimental/packages/api-logs/src/ProxyLoggerProvider.ts b/experimental/packages/api-logs/src/ProxyLoggerProvider.ts index 731facf719..952ae4da2a 100644 --- a/experimental/packages/api-logs/src/ProxyLoggerProvider.ts +++ b/experimental/packages/api-logs/src/ProxyLoggerProvider.ts @@ -24,13 +24,13 @@ export class ProxyLoggerProvider implements LoggerProvider { private _delegate?: LoggerProvider; getLogger( - _name: string, - _version?: string | undefined, - _options?: LoggerOptions | undefined + name: string, + version?: string | undefined, + options?: LoggerOptions | undefined ): Logger { return ( - this.getDelegateLogger(_name, _version, _options) ?? - new ProxyLogger(this, _name, _version, _options) + this.getDelegateLogger(name, version, options) ?? + new ProxyLogger(this, name, version, options) ); } From 14db9a866fbef1f9a15d64c9143983ad00a81b93 Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:00:43 -0700 Subject: [PATCH 5/7] Update changelog --- experimental/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 65b42de9e8..141d0c8039 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -7,7 +7,6 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change -* feat(api-logs): Add delegating no-op logger provider [#4861](https://github.com/open-telemetry/opentelemetry-js/pull/4861) @hectorhdzg * fix(instrumentation)!:remove unused description property from interface [#4847](https://github.com/open-telemetry/opentelemetry-js/pull/4847) @blumamir * feat(exporter-*-otlp-*)!: use transport interface in node.js exporters [#4743](https://github.com/open-telemetry/opentelemetry-js/pull/4743) @pichlermarc * (user-facing) `headers` was intended for internal use has been removed from all exporters @@ -26,6 +25,7 @@ All notable changes to experimental packages in this project will be documented * feat(otlp-transformer): Do not limit @opentelemetry/api upper range peerDependency [#4816](https://github.com/open-telemetry/opentelemetry-js/pull/4816) @mydea * feat(instrumentation-http): Allow to opt-out of instrumenting incoming/outgoing requests [#4643](https://github.com/open-telemetry/opentelemetry-js/pull/4643) @mydea * feat(sampler-jaeger-remote): added support of jaeger-remote-sampler according to this [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#jaegerremotesampler) [#4534](https://github.com/open-telemetry/opentelemetry-js/pull/4589) @legalimpurity +* feat(api-logs): Add delegating no-op logger provider [#4861](https://github.com/open-telemetry/opentelemetry-js/pull/4861) @hectorhdzg ### :bug: (Bug Fix) From 84eb5de8d9b2efc0c64c387d218bb0732bf8fc0e Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:38:56 -0700 Subject: [PATCH 6/7] test update --- experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index 9469b803cc..d24fe66b0b 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -117,6 +117,7 @@ describe('Node SDK', () => { // need to set OTEL_TRACES_EXPORTER to none since default value is otlp // which sets up an exporter and affects the context manager env.OTEL_TRACES_EXPORTER = 'none'; + env.OTEL_LOGS_EXPORTER = 'none'; const sdk = new NodeSDK({ autoDetectResources: false, }); From 0da7ee41bb16929cab8b5cec12a461d09e850c3c Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:43:29 -0700 Subject: [PATCH 7/7] Update changelog --- experimental/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 6c88cd65a1..33e8a3d0ce 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -9,6 +9,8 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) +* feat(api-logs): Add delegating no-op logger provider [#4861](https://github.com/open-telemetry/opentelemetry-js/pull/4861) @hectorhdzg + ### :bug: (Bug Fix) * fix(sampler-jaeger-remote): fixes an issue where package could emit unhandled promise rejections @Just-Sieb @@ -39,7 +41,6 @@ All notable changes to experimental packages in this project will be documented * feat(otlp-transformer): Do not limit @opentelemetry/api upper range peerDependency [#4816](https://github.com/open-telemetry/opentelemetry-js/pull/4816) @mydea * feat(instrumentation-http): Allow to opt-out of instrumenting incoming/outgoing requests [#4643](https://github.com/open-telemetry/opentelemetry-js/pull/4643) @mydea * feat(sampler-jaeger-remote): added support of jaeger-remote-sampler according to this [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#jaegerremotesampler) [#4534](https://github.com/open-telemetry/opentelemetry-js/pull/4589) @legalimpurity -* feat(api-logs): Add delegating no-op logger provider [#4861](https://github.com/open-telemetry/opentelemetry-js/pull/4861) @hectorhdzg ### :bug: (Bug Fix)