Skip to content

Commit 694f25b

Browse files
rochdevclaude
authored andcommitted
fix(electron): gate the Electron plugin behind an experimental flag (#9264)
* refactor(electron)!: gate the Electron plugin behind an experimental flag disabled in v7 The Electron integration (plugin + instrumentation) has moved to the standalone Electron SDK (see DataDog/electron-sdk#152). dd-trace keeps the plugin and instrumentation in place for backward compatibility, but gates it behind the existing experimental opt-in mechanism so it is disabled by default starting in v7, while remaining enabled by default on earlier majors. - ElectronPlugin.experimental is now DD_MAJOR >= 7, following the same opt-in pattern already used by other experimental plugins (e.g. nats). - major-overrides.js flips the documented DD_TRACE_ELECTRON_ENABLED default to false for majorVersion >= 7, evaluated at runtime against the branch's own DD_MAJOR so it stays accurate after backports. - tracer.js now prefers the Electron exporter over OTLP when both OTEL_TRACES_EXPORTER=otlp and experimental.exporter=electron are set, so Electron SDK spans keep reaching the IPC bridge instead of being silently routed to an OTLP endpoint. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(electron): skip the implicit OTel sampler default for the Electron exporter config/index.js forced OTel's parentbased_always_on sampler default (sampleRate=1) whenever OTEL_TRACES_EXPORTER=otlp, without the same Electron carve-out already present in opentracing/tracer.js's exporter selection. Electron SDK users with OTEL_* vars set for an unrelated telemetry pipeline could have dd-trace's sampling policy silently overridden even though their trace exporter correctly stayed on the Electron IPC bridge. An explicit OTEL_TRACES_SAMPLER still applies. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
1 parent d151db4 commit 694f25b

7 files changed

Lines changed: 50 additions & 4 deletions

File tree

packages/datadog-plugin-electron/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
'use strict'
22

3+
const { DD_MAJOR } = require('../../../version')
34
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
45
const ElectronIpcPlugin = require('./ipc')
56
const ElectronNetPlugin = require('./net')
67

78
class ElectronPlugin extends CompositePlugin {
89
static id = 'electron'
10+
static experimental = DD_MAJOR >= 7
911
static get plugins () {
1012
return {
1113
net: ElectronNetPlugin,

packages/dd-trace/src/config/index.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,9 +478,13 @@ class Config extends ConfigBase {
478478

479479
// Apply the OTel sampler when the user opted into OTel traces or explicitly set the sampler.
480480
// OTEL_TRACES_SAMPLER has `default: parentbased_always_on` (per OTel spec), so opt-in users
481-
// that don't set the sampler still get parent-based sampling.
481+
// that don't set the sampler still get parent-based sampling. Electron exporter spans go over
482+
// the Electron SDK's IPC bridge rather than OTLP (see opentracing/tracer.js), so an
483+
// OTEL_TRACES_EXPORTER=otlp set for an unrelated telemetry pipeline shouldn't also override
484+
// dd-trace's own sampling policy in that case.
482485
if (!trackedConfigOrigins.has('sampleRate') &&
483-
(trackedConfigOrigins.has('OTEL_TRACES_SAMPLER') || this.OTEL_TRACES_EXPORTER === 'otlp')) {
486+
(trackedConfigOrigins.has('OTEL_TRACES_SAMPLER') ||
487+
(this.OTEL_TRACES_EXPORTER === 'otlp' && this.experimental.exporter !== 'electron'))) {
484488
setAndTrack(this, 'sampleRate',
485489
getFromOtelSamplerMap(this.OTEL_TRACES_SAMPLER, this.OTEL_TRACES_SAMPLER_ARG))
486490
}

packages/dd-trace/src/config/major-overrides.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ function applyMajorOverrides (supportedConfigurations, majorVersion) {
5858
delete supportedConfigurations.DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED
5959
// eslint-disable-next-line eslint-rules/eslint-env-aliases
6060
dropAlias(supportedConfigurations.DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED, 'DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED')
61+
62+
if (majorVersion >= 7) {
63+
// The Electron plugin moved to the Electron SDK and is opt-in (disabled by default) from v7 on,
64+
// while remaining enabled by default on earlier majors (see ElectronPlugin.experimental).
65+
const electronEntry = supportedConfigurations.DD_TRACE_ELECTRON_ENABLED?.[0]
66+
if (electronEntry) electronEntry.default = 'false'
67+
}
6168
}
6269

6370
/**

packages/dd-trace/src/opentracing/tracer.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ class DatadogTracer {
3636
// (test_session/test_module/ test_suite/test) belong on the citestcycle
3737
// endpoint, not on an OTLP traces endpoint — otherwise users with OTEL_*
3838
// vars set in their environment (e.g. for a separate telemetry integration)
39-
// silently lose all test spans.
40-
if (config.OTEL_TRACES_EXPORTER === 'otlp' && !config.isCiVisibility) {
39+
// silently lose all test spans. The same applies to the Electron exporter:
40+
// spans must reach the Electron SDK's IPC bridge, not an OTLP endpoint,
41+
// even when OTEL_* vars are set for unrelated telemetry.
42+
if (config.OTEL_TRACES_EXPORTER === 'otlp' && !config.isCiVisibility &&
43+
config.experimental.exporter !== 'electron') {
4144
const { createOtlpTraceExporter } = require('../opentelemetry/trace')
4245
this._exporter = createOtlpTraceExporter(config)
4346
} else {

packages/dd-trace/test/config/index.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,19 @@ describe('Config', () => {
766766
assert.strictEqual(config.sampleRate, undefined)
767767
})
768768

769+
it('should not default OTEL_TRACES_SAMPLER when OTEL_TRACES_EXPORTER is otlp but the exporter is electron', () => {
770+
process.env.OTEL_TRACES_EXPORTER = 'otlp'
771+
const config = getConfig({ experimental: { exporter: 'electron' } })
772+
assert.strictEqual(config.sampleRate, undefined)
773+
})
774+
775+
it('should still respect an explicit OTEL_TRACES_SAMPLER when the exporter is electron', () => {
776+
process.env.OTEL_TRACES_EXPORTER = 'otlp'
777+
process.env.OTEL_TRACES_SAMPLER = 'always_off'
778+
const config = getConfig({ experimental: { exporter: 'electron' } })
779+
assert.strictEqual(config.sampleRate, 0)
780+
})
781+
769782
it('should keep OTEL_TRACES_EXPORTER=otlp', () => {
770783
process.env.OTEL_TRACES_EXPORTER = 'otlp'
771784
const config = getConfig()

packages/dd-trace/test/exporter.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const sinon = require('sinon')
99
require('./setup/core')
1010
const AgentExporter = require('../src/exporters/agent')
1111
const LogExporter = require('../src/exporters/log')
12+
const ElectronExporter = require('../src/exporters/electron')
1213
const { DATADOG_MINI_AGENT_PATH } = require('../src/constants')
1314

1415
describe('exporter', () => {
@@ -64,4 +65,10 @@ describe('exporter', () => {
6465

6566
assert.strictEqual(Exporter, LogExporter)
6667
})
68+
69+
it('should create an ElectronExporter when configured', () => {
70+
const Exporter = require('../src/exporter')('electron')
71+
72+
assert.strictEqual(Exporter, ElectronExporter)
73+
})
6774
})

packages/dd-trace/test/opentelemetry/traces.spec.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,16 @@ describe('OpenTelemetry Traces', () => {
748748
assert(!(tracer._exporter instanceof OtlpHttpTraceExporter),
749749
'Exporter should not be the OTLP exporter when OTEL_TRACES_EXPORTER is not otlp')
750750
})
751+
752+
it('DatadogTracer prefers the Electron exporter over OTLP when OTEL_TRACES_EXPORTER=otlp', () => {
753+
process.env.OTEL_TRACES_EXPORTER = 'otlp'
754+
const DatadogTracer = proxyquire.noPreserveCache()('../../src/opentracing/tracer', {})
755+
const ElectronExporter = require('../../src/exporters/electron')
756+
const config = getConfigFresh({ experimental: { exporter: 'electron' } })
757+
const tracer = new DatadogTracer(config)
758+
assert(tracer._exporter instanceof ElectronExporter,
759+
'Exporter should be the Electron exporter even when OTEL_TRACES_EXPORTER=otlp')
760+
})
751761
})
752762

753763
describe('Configurations', () => {

0 commit comments

Comments
 (0)