diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f67b78fe0e..33a35892f4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,12 +16,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: javascript - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 3f0b91598c..0254c89f8f 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -6,13 +6,20 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change +* fix(exporter-logs-otlp-http): programatic headers take precedence over environment variables [#2370](https://github.com/open-telemetry/opentelemetry-js/pull/4351) @Vunovati +* fix(exporter-logs-otlp-proto): programatic headers take precedence over environment variables [#2370](https://github.com/open-telemetry/opentelemetry-js/pull/4351) @Vunovati +* fix(exporter-trace-otlp-http): programatic headers take precedence over environment variables [#2370](https://github.com/open-telemetry/opentelemetry-js/pull/4351) @Vunovati +* fix(exporter-trace-otlp-proto): programatic headers take precedence over environment variables [#2370](https://github.com/open-telemetry/opentelemetry-js/pull/4351) @Vunovati + ### :rocket: (Enhancement) ### :bug: (Bug Fix) * fix(sdk-node): allow using samplers when the exporter is defined in the environment [#4394](https://github.com/open-telemetry/opentelemetry-js/pull/4394) @JacksonWeber - fix(instrumentation): use caret range on import-in-the-middle [#4380](https://github.com/open-telemetry/opentelemetry-js/pull/4380) @pichlermarc +* fix(instrumentation): use caret range on import-in-the-middle [#4380](https://github.com/open-telemetry/opentelemetry-js/pull/4380) @pichlermarc +* fix(instrumentation): do not import 'path' in browser runtimes [#4378](https://github.com/open-telemetry/opentelemetry-js/pull/4378) @pichlermarc + * Fixes a bug where bundling for web would fail due to `InstrumentationNodeModuleDefinition` importing `path` ### :books: (Refine Doc) diff --git a/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts index 25a1b194ab..56e4bad3d6 100644 --- a/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-http/src/platform/node/OTLPLogExporter.ts @@ -39,12 +39,13 @@ export class OTLPLogExporter timeoutMillis: getEnv().OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, ...config, }); - this.headers = { - ...this.headers, - ...baggageUtils.parseKeyPairsIntoRecord( + this.headers = Object.assign( + this.headers, + baggageUtils.parseKeyPairsIntoRecord( getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS ), - }; + config.headers + ); } convert(logRecords: ReadableLogRecord[]): IExportLogsServiceRequest { diff --git a/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts index 6dac23b580..83b389628a 100644 --- a/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts @@ -94,6 +94,18 @@ describe('OTLPLogExporter', () => { delete envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS; delete envSource.OTEL_EXPORTER_OTLP_LOGS_TIMEOUT; }); + + it('should override headers defined via env with headers defined in constructor', () => { + envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar,bar=foo'; + const collectorExporter = new OTLPLogExporter({ + headers: { + foo: 'constructor', + }, + }); + assert.strictEqual(collectorExporter.headers.foo, 'constructor'); + assert.strictEqual(collectorExporter.headers.bar, 'foo'); + envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; + }); }); describe('getDefaultUrl', () => { diff --git a/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts index 53191c0625..a8cdfc4c96 100644 --- a/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-proto/src/platform/node/OTLPLogExporter.ts @@ -50,7 +50,8 @@ export class OTLPLogExporter this.headers, baggageUtils.parseKeyPairsIntoRecord( getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS - ) + ), + config.headers ); } convert(logs: ReadableLogRecord[]): IExportLogsServiceRequest { diff --git a/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts index 0810109e81..ab918c992b 100644 --- a/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts @@ -92,6 +92,15 @@ describe('OTLPLogExporter - node with proto over http', () => { envSource.OTEL_EXPORTER_OTLP_ENDPOINT = ''; envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = ''; }); + it('should override url defined in env with url defined in constructor', () => { + envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar/'; + const constructorDefinedEndpoint = 'http://constructor/v1/logs'; + const collectorExporter = new OTLPLogExporter({ + url: constructorDefinedEndpoint, + }); + assert.strictEqual(collectorExporter.url, constructorDefinedEndpoint); + envSource.OTEL_EXPORTER_OTLP_ENDPOINT = ''; + }); it('should add root path when signal url defined in env contains no path and no root path', () => { envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://foo.bar'; const collectorExporter = new OTLPLogExporter(); @@ -143,6 +152,17 @@ describe('OTLPLogExporter - node with proto over http', () => { envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = ''; envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; }); + it('should override headers defined via env with headers defined in constructor', () => { + envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar,bar=foo'; + const collectorExporter = new OTLPLogExporter({ + headers: { + foo: 'constructor', + }, + }); + assert.strictEqual(collectorExporter.headers.foo, 'constructor'); + assert.strictEqual(collectorExporter.headers.bar, 'foo'); + envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; + }); }); describe('export', () => { diff --git a/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts index e4d3273239..aeb3b94ca7 100644 --- a/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts @@ -49,6 +49,7 @@ export class OTLPTraceExporter ...baggageUtils.parseKeyPairsIntoRecord( getEnv().OTEL_EXPORTER_OTLP_TRACES_HEADERS ), + ...config.headers, }; } diff --git a/experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts index 3de60027dc..e9af4ec37b 100644 --- a/experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts +++ b/experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts @@ -118,6 +118,15 @@ describe('OTLPTraceExporter - node with json over http', () => { envSource.OTEL_EXPORTER_OTLP_ENDPOINT = ''; envSource.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = ''; }); + it('should override url defined in env with url defined in constructor', () => { + envSource.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://foo.bar'; + const constructorDefinedEndpoint = 'http://constructor/v1/traces'; + const collectorExporter = new OTLPTraceExporter({ + url: constructorDefinedEndpoint, + }); + assert.strictEqual(collectorExporter.url, constructorDefinedEndpoint); + envSource.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = ''; + }); it('should add root path when signal url defined in env contains no path and no root path', () => { envSource.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://foo.bar'; const collectorExporter = new OTLPTraceExporter(); @@ -177,6 +186,17 @@ describe('OTLPTraceExporter - node with json over http', () => { envSource.OTEL_EXPORTER_OTLP_TRACES_HEADERS = ''; envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; }); + it('should override headers defined via env with headers defined in constructor', () => { + envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar,bar=foo'; + const collectorExporter = new OTLPTraceExporter({ + headers: { + foo: 'constructor', + }, + }); + assert.strictEqual(collectorExporter.headers.foo, 'constructor'); + assert.strictEqual(collectorExporter.headers.bar, 'foo'); + envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; + }); it('should use compression defined via env', () => { envSource.OTEL_EXPORTER_OTLP_COMPRESSION = 'gzip'; const collectorExporter = new OTLPTraceExporter(); diff --git a/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts index 210a16145a..be115583cd 100644 --- a/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-proto/src/platform/node/OTLPTraceExporter.ts @@ -52,6 +52,7 @@ export class OTLPTraceExporter ...baggageUtils.parseKeyPairsIntoRecord( getEnv().OTEL_EXPORTER_OTLP_TRACES_HEADERS ), + ...config.headers, }; } diff --git a/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts index c0a604ce90..b18c5a39de 100644 --- a/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts +++ b/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts @@ -103,6 +103,15 @@ describe('OTLPTraceExporter - node with proto over http', () => { envSource.OTEL_EXPORTER_OTLP_ENDPOINT = ''; envSource.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = ''; }); + it('should override url defined in env with url defined in constructor', () => { + envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar/'; + const constructorDefinedEndpoint = 'http://constructor/v1/traces'; + const collectorExporter = new OTLPTraceExporter({ + url: constructorDefinedEndpoint, + }); + assert.strictEqual(collectorExporter.url, constructorDefinedEndpoint); + envSource.OTEL_EXPORTER_OTLP_ENDPOINT = ''; + }); it('should add root path when signal url defined in env contains no path and no root path', () => { envSource.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://foo.bar'; const collectorExporter = new OTLPTraceExporter(); @@ -155,6 +164,17 @@ describe('OTLPTraceExporter - node with proto over http', () => { envSource.OTEL_EXPORTER_OTLP_TRACES_HEADERS = ''; envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; }); + it('should override headers defined via env with headers defined in constructor', () => { + envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar,bar=foo'; + const collectorExporter = new OTLPTraceExporter({ + headers: { + foo: 'constructor', + }, + }); + assert.strictEqual(collectorExporter.headers.foo, 'constructor'); + assert.strictEqual(collectorExporter.headers.bar, 'foo'); + envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; + }); }); describe('export', () => { diff --git a/experimental/packages/opentelemetry-instrumentation/src/instrumentationNodeModuleFile.ts b/experimental/packages/opentelemetry-instrumentation/src/instrumentationNodeModuleFile.ts index 574f17257e..edbe8ba72e 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/instrumentationNodeModuleFile.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/instrumentationNodeModuleFile.ts @@ -15,7 +15,7 @@ */ import { InstrumentationModuleFile } from './types'; -import { normalize } from 'path'; +import { normalize } from './platform/index'; export class InstrumentationNodeModuleFile implements InstrumentationModuleFile diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/browser/index.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/browser/index.ts index 0b238b42b8..4ad5c8f063 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/platform/browser/index.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/browser/index.ts @@ -15,3 +15,4 @@ */ export { InstrumentationBase } from './instrumentation'; +export { normalize } from './noop-normalize'; diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/browser/noop-normalize.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/browser/noop-normalize.ts new file mode 100644 index 0000000000..7b8aa40000 --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/browser/noop-normalize.ts @@ -0,0 +1,35 @@ +/* + * 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 { diag } from '@opentelemetry/api'; + +/** + * Placeholder normalize function to replace the node variant in browser runtimes, + * this should never be called and will perform a no-op and warn if it is called regardless. + * + * This is a workaround to fix https://github.com/open-telemetry/opentelemetry-js/issues/4373 until the instrumentation + * package can be made node-only. + * + * @param path input path + * @return unmodified path + * @internal + */ +export function normalize(path: string): string { + diag.warn( + 'Path normalization is not implemented for this platform. To silence this warning, ensure no node-specific instrumentations are loaded, and node-specific types (e.g. InstrumentationNodeModuleFile), are not used in a browser context)' + ); + return path; +} diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/index.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/index.ts index 81d3096252..f24b70eac5 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/platform/index.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { InstrumentationBase } from './node'; +export { InstrumentationBase, normalize } from './node'; diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/node/index.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/node/index.ts index 1e81931b2a..94f517dfa3 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/platform/node/index.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/node/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { InstrumentationBase } from './instrumentation'; +export { normalize } from './normalize'; diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/node/normalize.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/node/normalize.ts new file mode 100644 index 0000000000..83b83aaef2 --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/node/normalize.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export { normalize } from 'path'; diff --git a/experimental/packages/opentelemetry-instrumentation/test/browser/noop-normalize.test.ts b/experimental/packages/opentelemetry-instrumentation/test/browser/noop-normalize.test.ts new file mode 100644 index 0000000000..aedcb975e7 --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation/test/browser/noop-normalize.test.ts @@ -0,0 +1,24 @@ +/* + * 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 { normalize } from '../../src/platform/browser'; + +describe('noop-normalize', function () { + it('should not normalize input', function () { + assert.strictEqual(normalize('/tmp/foo/../bar'), '/tmp/foo/../bar'); + }); +});