From 9444363f827e560cf080b9bbe53b2fe4fab8fa0a Mon Sep 17 00:00:00 2001 From: Brian Marks Date: Thu, 23 Jul 2026 18:31:37 -0400 Subject: [PATCH 1/2] feat(startup-log): add OTLP export flags to startup diagnostic log Add three boolean fields to the DATADOG TRACER CONFIGURATION startup log indicating whether the tracer exports each telemetry signal over OTLP: - otlp_traces_export_enabled (OTEL_TRACES_EXPORTER === 'otlp', excluding Test Optimization mode, which keeps test spans on the citestcycle endpoint) - otlp_metrics_export_enabled (DD_METRICS_OTEL_ENABLED) - otlp_logs_export_enabled (DD_LOGS_OTEL_ENABLED) The snake_case keys are chosen for cross-language startup-log consistency. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/dd-trace/src/startup-log.js | 3 + packages/dd-trace/test/startup-log.spec.js | 72 +++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/packages/dd-trace/src/startup-log.js b/packages/dd-trace/src/startup-log.js index 7e74e3d508..52fafff7f5 100644 --- a/packages/dd-trace/src/startup-log.js +++ b/packages/dd-trace/src/startup-log.js @@ -108,6 +108,9 @@ function configInfo () { profiling_enabled: profilingEnabled === 'true' || profilingEnabled === 'auto', appsec_enabled: config.appsec.enabled, data_streams_enabled: !!config.dsmEnabled, + otlp_traces_export_enabled: config.OTEL_TRACES_EXPORTER === 'otlp' && !config.isCiVisibility, + otlp_metrics_export_enabled: !!config.DD_METRICS_OTEL_ENABLED, + otlp_logs_export_enabled: !!config.DD_LOGS_OTEL_ENABLED, } } diff --git a/packages/dd-trace/test/startup-log.spec.js b/packages/dd-trace/test/startup-log.spec.js index aa0df80865..546dc6959d 100644 --- a/packages/dd-trace/test/startup-log.spec.js +++ b/packages/dd-trace/test/startup-log.spec.js @@ -3,7 +3,7 @@ const assert = require('node:assert') const os = require('node:os') -const { describe, it, before, afterEach } = require('mocha') +const { describe, it, before, beforeEach, afterEach } = require('mocha') const sinon = require('sinon') require('./setup/core') @@ -80,6 +80,9 @@ describe('startup logging', () => { assert.strictEqual(logObj.debug, true) assert.strictEqual(logObj.appsec_enabled, true) assert.strictEqual(logObj.data_streams_enabled, true) + assert.strictEqual('otlp_traces_export_enabled' in logObj, true) + assert.strictEqual('otlp_metrics_export_enabled' in logObj, true) + assert.strictEqual('otlp_logs_export_enabled' in logObj, true) }) it('logIntegrations should output loaded integrations', () => { @@ -121,6 +124,9 @@ describe('startup logging', () => { integrations_loaded: ['http', 'fs', 'semver'], appsec_enabled: true, data_streams_enabled: true, + otlp_traces_export_enabled: false, + otlp_metrics_export_enabled: false, + otlp_logs_export_enabled: false, }) }) }) @@ -314,3 +320,67 @@ describe('profiling_enabled', () => { }) }) }) + +describe('otlp export flags', () => { + function clearOtlpEnv () { + delete process.env.OTEL_TRACES_EXPORTER + delete process.env.DD_METRICS_OTEL_ENABLED + delete process.env.DD_LOGS_OTEL_ENABLED + } + + // Clear before each test too: this repo's dev shells export OTEL_TRACES_EXPORTER=otlp, + // which would otherwise leak into the default-state assertion. + beforeEach(clearOtlpEnv) + afterEach(clearOtlpEnv) + + function startupLogObj (configOptions) { + sinon.stub(console, 'warn') + delete require.cache[require.resolve('../src/startup-log')] + const { + setStartupLogConfig, + startupLog, + } = require('../src/startup-log') + process.env.DD_TRACE_STARTUP_LOGS = 'true' + setStartupLogConfig(getConfigFresh(configOptions)) + startupLog() + /* eslint-disable-next-line no-console */ + const warnStub = /** @type {sinon.SinonStub} */ (console.warn) + const logObj = JSON.parse(warnStub.firstCall.args[0].replace('DATADOG TRACER CONFIGURATION - ', '')) + warnStub.restore() + return logObj + } + + it('should default to false when no OTLP env vars are set', () => { + const logObj = startupLogObj() + assert.strictEqual(logObj.otlp_traces_export_enabled, false) + assert.strictEqual(logObj.otlp_metrics_export_enabled, false) + assert.strictEqual(logObj.otlp_logs_export_enabled, false) + }) + + it('otlp_traces_export_enabled should be true when OTEL_TRACES_EXPORTER is otlp', () => { + process.env.OTEL_TRACES_EXPORTER = 'otlp' + assert.strictEqual(startupLogObj().otlp_traces_export_enabled, true) + }) + + it('otlp_traces_export_enabled should be false when OTEL_TRACES_EXPORTER is none', () => { + process.env.OTEL_TRACES_EXPORTER = 'none' + assert.strictEqual(startupLogObj().otlp_traces_export_enabled, false) + }) + + it('otlp_traces_export_enabled should be false in Test Optimization mode even when exporter is otlp', () => { + // Test Optimization keeps test spans on the citestcycle endpoint, so the OTLP + // trace exporter is not used regardless of OTEL_TRACES_EXPORTER (see opentracing/tracer.js). + process.env.OTEL_TRACES_EXPORTER = 'otlp' + assert.strictEqual(startupLogObj({ isCiVisibility: true }).otlp_traces_export_enabled, false) + }) + + it('otlp_metrics_export_enabled should be true when DD_METRICS_OTEL_ENABLED is true', () => { + process.env.DD_METRICS_OTEL_ENABLED = 'true' + assert.strictEqual(startupLogObj().otlp_metrics_export_enabled, true) + }) + + it('otlp_logs_export_enabled should be true when DD_LOGS_OTEL_ENABLED is true', () => { + process.env.DD_LOGS_OTEL_ENABLED = 'true' + assert.strictEqual(startupLogObj().otlp_logs_export_enabled, true) + }) +}) From 1ccdd7600f3ca0da64b664800e299f153c2575c5 Mon Sep 17 00:00:00 2001 From: Brian Marks Date: Fri, 24 Jul 2026 18:41:04 -0400 Subject: [PATCH 2/2] test(startup-log): clear all OTEL exporter env vars in OTLP export flag tests The `otlp export flags` cleanup only cleared OTEL_TRACES_EXPORTER, leaving OTEL_METRICS_EXPORTER and OTEL_LOGS_EXPORTER set. In shells that export OTEL_METRICS_EXPORTER=none, config forces DD_METRICS_OTEL_ENABLED back to false, so the metrics positive case no longer observes the enabled flag. Clear all three OTEL_*_EXPORTER selectors in the shared cleanup so the tests are deterministic regardless of the surrounding shell. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/dd-trace/test/startup-log.spec.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/dd-trace/test/startup-log.spec.js b/packages/dd-trace/test/startup-log.spec.js index 546dc6959d..47f6a0b732 100644 --- a/packages/dd-trace/test/startup-log.spec.js +++ b/packages/dd-trace/test/startup-log.spec.js @@ -324,12 +324,15 @@ describe('profiling_enabled', () => { describe('otlp export flags', () => { function clearOtlpEnv () { delete process.env.OTEL_TRACES_EXPORTER + delete process.env.OTEL_METRICS_EXPORTER + delete process.env.OTEL_LOGS_EXPORTER delete process.env.DD_METRICS_OTEL_ENABLED delete process.env.DD_LOGS_OTEL_ENABLED } - // Clear before each test too: this repo's dev shells export OTEL_TRACES_EXPORTER=otlp, - // which would otherwise leak into the default-state assertion. + // Datadog-instrumented dev shells export the OTEL_*_EXPORTER selectors: a leaked + // OTEL_TRACES_EXPORTER=otlp corrupts the default-state assertion, and OTEL_METRICS_EXPORTER=none + // makes config force DD_METRICS_OTEL_ENABLED back to false, breaking the metrics positive case. beforeEach(clearOtlpEnv) afterEach(clearOtlpEnv)