feat(telemetry): forward session ids through data-pipeline FFI#8500
feat(telemetry): forward session ids through data-pipeline FFI#8500khanayan123 wants to merge 1 commit intomasterfrom
Conversation
Closes the gap between PR #8352 (managed telemetry transport) and the libdatadog-backed telemetry transport that engages when DD_TRACE_DATA_PIPELINE_ENABLED=true. - Extend the P/Invoke struct TelemetryClientConfiguration with SessionId, RootSessionId, and ParentSessionId CharSlice fields to mirror the new libdd-data-pipeline-ffi TelemetryClientConfig layout (DataDog/libdatadog#1908). - Populate SessionId from Tracer.RuntimeId and RootSessionId from RuntimeId.GetRootSessionId() in ManagedTraceExporter, matching the header semantics used by the managed transport in #8352. ParentSessionId is left unset, consistent with the managed path. Requires a libdatadog bump that includes the new FFI fields (DataDog/libdatadog#1908); the struct is size-sensitive so the native library and the managed struct must move together. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BenchmarksBenchmark execution time: 2026-04-22 15:26:34 Comparing candidate commit e2916e7 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 27 metrics, 0 unstable metrics, 58 known flaky benchmarks, 29 flaky benchmarks without significant changes.
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8500) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (74ms) : 70, 79
master - mean (73ms) : 70, 77
section Bailout
This PR (8500) - mean (79ms) : 75, 84
master - mean (77ms) : 74, 80
section CallTarget+Inlining+NGEN
This PR (8500) - mean (1,085ms) : 1035, 1136
master - mean (1,085ms) : 1036, 1134
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (118ms) : 111, 125
master - mean (114ms) : 110, 119
section Bailout
This PR (8500) - mean (117ms) : 113, 122
master - mean (115ms) : 111, 118
section CallTarget+Inlining+NGEN
This PR (8500) - mean (807ms) : 781, 833
master - mean (794ms) : 765, 824
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (103ms) : 96, 110
master - mean (105ms) : 101, 110
section Bailout
This PR (8500) - mean (102ms) : 99, 105
master - mean (103ms) : 99, 108
section CallTarget+Inlining+NGEN
This PR (8500) - mean (947ms) : 911, 983
master - mean (947ms) : 900, 993
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (104ms) : 98, 109
master - mean (101ms) : 96, 106
section Bailout
This PR (8500) - mean (104ms) : 99, 109
master - mean (105ms) : 101, 110
section CallTarget+Inlining+NGEN
This PR (8500) - mean (830ms) : 789, 870
master - mean (826ms) : 784, 869
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (210ms) : 200, 221
master - mean (203ms) : 195, 212
section Bailout
This PR (8500) - mean (214ms) : 203, 225
master - mean (207ms) : 198, 215
section CallTarget+Inlining+NGEN
This PR (8500) - mean (1,247ms) : 1162, 1332
master - mean (1,202ms) : 1158, 1247
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (302ms) : 282, 322
master - mean (294ms) : 280, 307
section Bailout
This PR (8500) - mean (303ms) : 286, 321
master - mean (295ms) : 280, 311
section CallTarget+Inlining+NGEN
This PR (8500) - mean (1,003ms) : 969, 1037
master - mean (981ms) : 952, 1011
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (297ms) : 277, 316
master - mean (286ms) : 276, 297
section Bailout
This PR (8500) - mean (297ms) : 279, 314
master - mean (286ms) : 276, 297
section CallTarget+Inlining+NGEN
This PR (8500) - mean (1,182ms) : 1137, 1227
master - mean (1,169ms) : 1122, 1216
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8500) - mean (291ms) : 277, 305
master - mean (289ms) : 276, 301
section Bailout
This PR (8500) - mean (292ms) : 277, 308
master - mean (290ms) : 275, 306
section CallTarget+Inlining+NGEN
This PR (8500) - mean (1,083ms) : 982, 1184
master - mean (1,070ms) : 983, 1158
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Summary
Closes the session-id parity gap between PR #8352 (managed telemetry transport) and the libdatadog-backed telemetry transport that engages when
DD_TRACE_DATA_PIPELINE_ENABLED=true.PR #8352 added
DD-Session-IDandDD-Root-Session-IDheaders for telemetry traffic on the managedHttpClientRequestFactory/ApiWebRequestFactorypath. WhenDataPipelineEnabled=true, telemetry is instead originated by libdatadog's telemetry worker and those managed headers never apply. Until now, there was no FFI surface to carry session IDs into libdatadog's worker from the trace-exporter path.This PR plumbs the IDs through the new FFI fields added in DataDog/libdatadog#1908:
TelemetryClientConfiguration— addsSessionId,RootSessionId, andParentSessionIdCharSlicefields, mirroring thelibdd-data-pipeline-ffi::TelemetryClientConfiglayout.ManagedTraceExporter.CreateTraceExporter— populatesSessionId = Tracer.RuntimeIdandRootSessionId = RuntimeId.GetRootSessionId(), matching the exact header semantics used by the managed transport in PR feat: Stable Session ID headers for telemetry #8352.ParentSessionIdis left unset, consistent with the managed path (the .NET tracer does not currently emitDD-Parent-Session-ID).On the libdatadog side, empty
CharSlices are treated as unset, so consumers that don't populate these fields behave unchanged. The worker already suppressesDD-Root-Session-IDwhen it equals the session id, so we can forward both unconditionally without emitting redundant headers on the wire.Dependencies
Requires DataDog/libdatadog#1908 — the native
TelemetryClientConfigstruct must match the new managed layout. This PR is draft and cannot merge until libdatadog ships the corresponding fields and the vendored libdatadog version is bumped here.Test plan
dotnet build -c Debug— all four TFMs (net461, netstandard2.0, netcoreapp3.1, net6.0) compile cleanly with no warnings.DD_TRACE_DATA_PIPELINE_ENABLED=true.DD-Session-IDandDD-Root-Session-IDheaders appear on telemetry HTTP requests emitted by the libdatadog worker in this mode.Risks / rollout
TelemetryClientConfigurationis a[StructLayout(LayoutKind.Sequential)]struct marshaled viaMarshal.StructureToPtr. Size/layout must match libdatadog — hence the hard dependency on Clean the workspace before building on ARM64 #1908. Mismatched layouts would cause silent memory corruption inside the FFI call. We must not merge this until the libdatadog bump lands.DataPipelineEnabled=truecohort today is opt-in and constrained (force-disabled under stats computation, UDS-on-Windows, SSI, or libdatadog unavailability). Blast radius is small.ManagedTraceExporterneeds to populate it.Related
libdatadog pr: DataDog/libdatadog#1822