diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 8a9d9a53810..4135754501f 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -17,6 +17,9 @@ All notable changes to experimental packages in this project will be documented ### :bug: (Bug Fix) * fix(exporter-prometheus): avoid invoking callback synchronously [#4431](https://github.com/open-telemetry/opentelemetry-js/pull/4431) @legendecas +* fix(exporter-logs-otlp-grpc): set User-Agent header [#4398](https://github.com/open-telemetry/opentelemetry-js/pull/4398) @Vunovati +* fix(exporter-logs-otlp-http): set User-Agent header [#4398](https://github.com/open-telemetry/opentelemetry-js/pull/4398) @Vunovati +* fix(exporter-logs-otlp-proto): set User-Agent header [#4398](https://github.com/open-telemetry/opentelemetry-js/pull/4398) @Vunovati ### :books: (Refine Doc) diff --git a/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts b/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts index 675ce83db0a..19b747fca72 100644 --- a/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts +++ b/experimental/packages/exporter-logs-otlp-grpc/src/OTLPLogExporter.ts @@ -28,6 +28,11 @@ import { createExportLogsServiceRequest, IExportLogsServiceRequest, } from '@opentelemetry/otlp-transformer'; +import { VERSION } from './version'; + +const USER_AGENT = { + 'User-Agent': `OTel-OTLP-Exporter-JavaScript/${VERSION}`, +}; /** * OTLP Logs Exporter for Node @@ -38,9 +43,12 @@ export class OTLPLogExporter { constructor(config: OTLPGRPCExporterConfigNode = {}) { super(config); - const headers = baggageUtils.parseKeyPairsIntoRecord( - getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS - ); + const headers = { + ...USER_AGENT, + ...baggageUtils.parseKeyPairsIntoRecord( + getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS + ), + }; this.metadata ||= new Metadata(); for (const [k, v] of Object.entries(headers)) { this.metadata.set(k, v); diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts index 9bda910924c..bb57df4a4ea 100644 --- a/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts @@ -37,6 +37,7 @@ import { IExportLogsServiceRequest, IResourceLogs, } from '@opentelemetry/otlp-transformer'; +import { VERSION } from '../src/version'; const logsServiceProtoPath = 'opentelemetry/proto/collector/logs/v1/logs_service.proto'; @@ -333,6 +334,12 @@ describe('when configuring via environment', () => { envSource.OTEL_EXPORTER_OTLP_ENDPOINT = ''; envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = ''; }); + it('should include user-agent header by default', () => { + const collectorExporter = new OTLPLogExporter(); + assert.deepStrictEqual(collectorExporter.metadata?.get('User-Agent'), [ + `OTel-OTLP-Exporter-JavaScript/${VERSION}`, + ]); + }); it('should use headers defined via env', () => { envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar'; const collectorExporter = new OTLPLogExporter(); 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 56e4bad3d69..9181b082cf9 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 @@ -25,6 +25,11 @@ import { OTLPExporterNodeBase } from '@opentelemetry/otlp-exporter-base'; import { createExportLogsServiceRequest } from '@opentelemetry/otlp-transformer'; import { getDefaultUrl } from '../config'; +import { VERSION } from '../../version'; + +const USER_AGENT = { + 'User-Agent': `OTel-OTLP-Exporter-JavaScript/${VERSION}`, +}; /** * Collector Logs Exporter for Node @@ -39,13 +44,14 @@ export class OTLPLogExporter timeoutMillis: getEnv().OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, ...config, }); - this.headers = Object.assign( - this.headers, - baggageUtils.parseKeyPairsIntoRecord( + this.headers = { + ...this.headers, + ...USER_AGENT, + ...baggageUtils.parseKeyPairsIntoRecord( getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS ), - config.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 83b389628a4..5920657b5b6 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 @@ -31,6 +31,7 @@ import { import { PassThrough, Stream } from 'stream'; import { IExportLogsServiceRequest } from '@opentelemetry/otlp-transformer'; import { ExportResultCode } from '@opentelemetry/core'; +import { VERSION } from '../../src/version'; let fakeRequest: PassThrough; @@ -79,6 +80,14 @@ describe('OTLPLogExporter', () => { assert.ok(exporter instanceof OTLPLogExporter); }); + it('should include user-agent header by default', () => { + const exporter = new OTLPLogExporter(); + assert.strictEqual( + exporter.headers['User-Agent'], + `OTel-OTLP-Exporter-JavaScript/${VERSION}` + ); + }); + it('should use headers defined via env', () => { envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'foo=bar'; const exporter = new OTLPLogExporter(); 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 a8cdfc4c969..caec7352fff 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 @@ -30,6 +30,11 @@ import { } from '@opentelemetry/otlp-transformer'; import { ReadableLogRecord, LogRecordExporter } from '@opentelemetry/sdk-logs'; +import { VERSION } from '../../version'; + +const USER_AGENT = { + 'User-Agent': `OTel-OTLP-Exporter-JavaScript/${VERSION}`, +}; const DEFAULT_COLLECTOR_RESOURCE_PATH = 'v1/logs'; const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURCE_PATH}`; @@ -46,13 +51,14 @@ export class OTLPLogExporter { constructor(config: OTLPExporterConfigBase = {}) { super(config); - this.headers = Object.assign( - this.headers, - baggageUtils.parseKeyPairsIntoRecord( + this.headers = { + ...this.headers, + ...USER_AGENT, + ...baggageUtils.parseKeyPairsIntoRecord( getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS ), - config.headers - ); + ...config.headers, + }; } convert(logs: ReadableLogRecord[]): IExportLogsServiceRequest { return createExportLogsServiceRequest(logs); 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 ab918c992b6..9778c950464 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 @@ -39,6 +39,7 @@ import { } from '@opentelemetry/otlp-proto-exporter-base'; import { IExportLogsServiceRequest } from '@opentelemetry/otlp-transformer'; import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; +import { VERSION } from '../../src/version'; let fakeRequest: PassThrough; @@ -137,6 +138,13 @@ describe('OTLPLogExporter - node with proto over http', () => { ); envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = ''; }); + it('should include user-agent header by default', () => { + const exporter = new OTLPLogExporter(); + assert.strictEqual( + exporter.headers['User-Agent'], + `OTel-OTLP-Exporter-JavaScript/${VERSION}` + ); + }); it('should use headers defined via env', () => { envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'foo=bar'; const collectorExporter = new OTLPLogExporter();