Skip to content

Commit ec9b17f

Browse files
szegediBridgeAR
authored andcommitted
feat(otel-thread-ctx): Node.js OTEP-4947 thread-context writer (#9210)
Mirrors the active trace ID, span ID, local root span ID and current endpoint into a thread-local OTEP-4947 record, so an out-of-process eBPF reader can attribute samples without going through the tracer. The record is discovered via the otel_thread_ctx_nodejs_v1 TLS symbol exported by the @datadog/pprof addon, and decoded using an OTEP-4719 process context published through libdatadog's process discovery (threadlocal.* attribute key map, schema version, and the V8 layout constants a reader needs to walk into the record). Off by default, behind DD_TRACE_OTEL_CTX_ENABLED. Requires Linux and an active AsyncContextFrame (default from Node 24, opt-in on 22/23), and refuses to start unless the installed @datadog/pprof exposes every API member the writer calls and a context can actually be installed in this process — an unusable pprof costs a log line rather than an exception thrown from a hot-path diagnostic channel subscriber. One ThreadContext is built per span on first activation and cached on the span, so re-entry in another async-context frame re-installs the same reference rather than allocating. On span finish the record is invalidated in place, which drops it out of scope for every frame that inherited it — sibling frames and continuations the span scheduled before finishing — since no later storage event reaches those. The endpoint is held back until its value settles: plugins publish interim routing tags, and datadog-plugin-next seeds resource.name with the bare request method, so publishing early would leave a reader attributing samples to "GET". Once a request's endpoint resolves it is appended to every record built under that request, the request span's own and each descendant's.
1 parent 4feb07b commit ec9b17f

19 files changed

Lines changed: 1854 additions & 107 deletions

.github/CODEOWNERS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,13 @@
369369
/integration-tests/profiler/ @DataDog/profiling-js
370370

371371
/packages/dd-trace/*/profiling/ @DataDog/profiling-js
372+
/packages/dd-trace/src/otel-thread-ctx.js @DataDog/profiling-js
372373
/packages/dd-trace/src/profiler.js @DataDog/profiling-js
374+
/packages/dd-trace/src/storage-channels.js @DataDog/profiling-js @DataDog/apm-sdk-capabilities-js
375+
/packages/dd-trace/src/web-tags-cache.js @DataDog/profiling-js
373376
/packages/dd-trace/test/exporters/common/form-data.spec.js @DataDog/profiling-js
377+
/packages/dd-trace/test/otel-thread-ctx.spec.js @DataDog/profiling-js
378+
/packages/dd-trace/test/web-tags-cache.spec.js @DataDog/profiling-js
374379

375380
# Language Platform
376381
/* @DataDog/lang-platform-js

.github/workflows/profiling.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
- uses: ./.github/actions/install
3333
- run: npm run test:profiler:ci
3434
- run: npm run test:integration:profiler:coverage
35+
- run: npm run test:otel-thread-ctx
3536
- uses: ./.github/actions/coverage
3637
with:
3738
flags: profiling-macos
@@ -60,6 +61,7 @@ jobs:
6061
- uses: ./.github/actions/node/latest
6162
- run: npm run test:profiler:ci
6263
- run: npm run test:integration:profiler:coverage
64+
- run: npm run test:otel-thread-ctx
6365
- uses: ./.github/actions/coverage
6466
with:
6567
flags: profiling-ubuntu
@@ -118,6 +120,7 @@ jobs:
118120
) | ForEach-Object { "$_=" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 }
119121
- run: npm run test:profiler:ci
120122
- run: npm run test:integration:profiler:coverage
123+
- run: npm run test:otel-thread-ctx
121124
- uses: ./.github/actions/node-crash-report
122125
if: failure()
123126
# Upload any WER minidumps that landed during this job, even on

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
"test:plugins:upstream": "node ./packages/dd-trace/test/plugins/suite.js",
7272
"test:profiler": "node scripts/mocha-parallel-files.js --expose-gc --timeout 30000 -- \"packages/dd-trace/test/profiling/**/*.spec.js\"",
7373
"test:profiler:ci": "node scripts/c8-ci.js test:profiler",
74+
"test:otel-thread-ctx": "mocha --timeout 60000 packages/dd-trace/test/otel-thread-ctx.spec.js",
75+
"test:docker:otel-thread-ctx": "./scripts/docker/run-otel-thread-ctx-spec.sh",
7476
"test:integration": "mocha --timeout 60000 \"integration-tests/*.spec.js\"",
7577
"test:integration:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/*.spec.js\"",
7678
"test:integration:aiguard": "mocha --timeout 60000 \"integration-tests/aiguard/*.spec.js\"",
@@ -180,7 +182,7 @@
180182
"opentracing": ">=0.14.7"
181183
},
182184
"optionalDependencies": {
183-
"@datadog/libdatadog": "0.9.4",
185+
"@datadog/libdatadog": "0.12.1",
184186
"@datadog/native-appsec": "11.0.1",
185187
"@datadog/native-iast-taint-tracking": "4.2.0",
186188
"@datadog/native-metrics": "3.1.2",

packages/dd-trace/src/config/generated-config-types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ export interface GeneratedConfig {
340340
DD_TRACE_OPENSEARCH_PROJECT_OPENSEARCH_ENABLED: boolean;
341341
DD_TRACE_OPENTELEMETRY_SDK_TRACE_NODE_ENABLED: boolean;
342342
DD_TRACE_ORACLEDB_ENABLED: boolean;
343+
DD_TRACE_OTEL_CTX_ENABLED: boolean;
343344
DD_TRACE_OTEL_ENABLED: boolean;
344345
DD_TRACE_OTEL_SEMANTICS_ENABLED: boolean;
345346
DD_TRACE_PASSPORT_ENABLED: boolean;
@@ -1040,6 +1041,7 @@ export interface GeneratedEnvVarConfig {
10401041
DD_TRACE_OPENSEARCH_PROJECT_OPENSEARCH_ENABLED: boolean;
10411042
DD_TRACE_OPENTELEMETRY_SDK_TRACE_NODE_ENABLED: boolean;
10421043
DD_TRACE_ORACLEDB_ENABLED: boolean;
1044+
DD_TRACE_OTEL_CTX_ENABLED: boolean;
10431045
DD_TRACE_OTEL_ENABLED: boolean;
10441046
DD_TRACE_OTEL_SEMANTICS_ENABLED: boolean;
10451047
DD_TRACE_PARTIAL_FLUSH_MIN_SPANS: number;

packages/dd-trace/src/config/supported-configurations.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,6 +3518,13 @@
35183518
"default": "false"
35193519
}
35203520
],
3521+
"DD_TRACE_OTEL_CTX_ENABLED": [
3522+
{
3523+
"implementation": "A",
3524+
"type": "boolean",
3525+
"default": "false"
3526+
}
3527+
],
35213528
"DD_TRACE_PARTIAL_FLUSH_MIN_SPANS": [
35223529
{
35233530
"implementation": "B",

0 commit comments

Comments
 (0)