Commit 92cdfe6
Implement stable session identifier headers for telemetry (#295)
* Implement stable session identifier headers for telemetry
Adds DD-Session-ID and DD-Root-Session-ID HTTP headers to all telemetry
requests per the Stable Service Instance Identifier RFC.
- DD-Session-ID is always set to the tracer's runtime_id
- DD-Root-Session-ID is only set when it differs from the session ID
(i.e. when running as a child process)
- Root session ID is propagated to exec'd children via
_DD_ROOT_CPP_SESSION_ID env var, read in finalize_config()
- _DD_ROOT_CPP_SESSION_ID registered in the environment variable
registry and supported-configurations.json
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Resync supported-configurations.json via config-inversion tool
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix config-inversion: output null default for _DD_ROOT_CPP_SESSION_ID
The central registry expects null as the default value. Change the
macro default from "" to nullptr and teach the config-inversion tool
to emit JSON null for nullptr defaults.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Match registry: _DD_ROOT_CPP_SESSION_ID implementation B, default ""
The central registry has this config as implementation B with an empty
string default. Update environment.h to use "" and teach config-inversion
to emit "B" for this var via an override map.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Revert to implementation A with null default for _DD_ROOT_CPP_SESSION_ID
Registry entry had trailing space in name (now fixed by registry team).
Use implementation A and null default to match registry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update include/datadog/environment.h
Co-authored-by: Zach Montoya <zach.montoya@datadoghq.com>
* fix: address PR review — use empty string default, move env lookup
- Change _DD_ROOT_CPP_SESSION_ID default from nullptr to "" in
environment.h
- Move _DD_ROOT_CPP_SESSION_ID lookup into load_tracer_env_config()
so it follows the same pattern as other env var loading
- Add root_session_id field to TracerConfig struct
- Update supported-configurations.json to implementation B with
default ""
- No changes to config-inversion tool
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: revert config-inversion changes, no longer needed with "" default
Since _DD_ROOT_CPP_SESSION_ID now defaults to "" (not nullptr), the
config-inversion tool doesn't need the nullptr specialization. Revert
to original to_string_any and fix implementation marker to "A".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: revert unrelated formatting, deduplicate session headers, fix Windows setenv
- Revert whitespace-only changes (const char * style) in environment.cpp
and environment.h to keep the diff focused on the feature.
- Extract set_session_headers() helper in telemetry_impl.cpp to avoid
duplicating session header logic in app_started() and send_payload().
- Fix Windows _putenv_s path to check getenv() first, matching the
POSIX setenv(..., 0) "don't overwrite" semantics.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update test/telemetry/test_telemetry.cpp
Co-authored-by: Zach Montoya <zach.montoya@datadoghq.com>
* fix: include request_headers in MockHTTPClient::clear()
The suggestion to use client->clear() instead of
client->request_headers.items.clear() exposed that clear() only
reset request_body. Update it to also clear request_headers so the
heartbeat session-header test validates fresh headers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address review feedback from xlamorlette
- Rename environment::set to set_if_not_set for clarity
- Add config registry link and comment for _DD_ROOT_CPP_SESSION_ID
- Add backward-compatible 3-param TracerSignature constructor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: move config registry link to top of file, remove inline link
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: remove inline comment on _DD_ROOT_CPP_SESSION_ID
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: simplify telemetry init() using 3-param TracerSignature constructor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: fix clang-format violation in telemetry.cpp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address review feedback from xlamorlette
- Rename constructor params to match member names
- Rename rid to session_rid in session header tests
- Use 3-param TracerSignature constructor where root_session == runtime_id
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: replace env var with singleton for root session ID
Replace _DD_ROOT_CPP_SESSION_ID environment variable propagation with a
thread-safe singleton (std::call_once). The singleton is immutable after
first init, making it safe across forks.
- Add set_root_session_id/get_root_session_id in tracer_config
- Remove _DD_ROOT_CPP_SESSION_ID from environment registry
- Remove environment::set_if_not_set (no longer needed)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: store session_id in local var, simplify app_started() via send_payload()
Address reviewer nits:
- Cache sig.runtime_id.string() in set_session_headers to avoid double call
- Replace app_started() body with send_payload("app-started", ...) since
send_payload is a superset with additional response metrics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: move root session ID singleton to internal header
Move set/get into datadog::tracing::root_session_id namespace in
src/datadog/root_session_id.h (internal header), matching the codebase
pattern of keeping implementation details out of public headers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add root_session_id.h to Bazel BUILD file
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: move root session ID singleton internals to .cpp file
Hide instance() and flag() in an anonymous namespace in
root_session_id.cpp, matching the telemetry Meyer's singleton pattern.
Only set() and get() are exposed in the header.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: revert formatting-only changes in environment.cpp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: revert formatting-only changes in tracer_config.cpp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: revert unnecessary changes in test_remote_config.cpp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Revert "chore: revert unnecessary changes in test_remote_config.cpp"
This reverts commit 212fc67.
* chore: revert test_remote_config.cpp to main (no functional changes needed)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: restore original TracerSignature style in test_telemetry.cpp
Keep inline comment style matching main for unchanged test sections.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: revert unnecessary changes in test_datadog_agent.cpp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: replace std::call_once with mutex+bool guard in root session singleton
std::call_once can throw std::system_error on some glibc versions due
to pthread_once issues. Use a simple mutex+bool guard instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* simplify: use static local singleton pattern for root session ID
Match the codebase's existing singleton pattern (static local variable).
No mutex or call_once needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add mutex to root session ID singleton for thread safety
Protect concurrent set() calls with std::mutex, matching the codebase's
standard pattern for shared state protection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use std::atomic for root session ID singleton guard
Replace std::mutex with std::atomic<bool> compare_exchange_strong to
avoid potential pthread issues in Docker/CI environments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* revert: restore original app_started() implementation
Revert the app_started() → send_payload() simplification as it was out
of scope for this PR. Keep only the session headers addition.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: simplify root session ID to single get_or_init() singleton
Replace separate set()/get() with a single get_or_init(runtime_id) that
initializes on first call and returns the stored value on subsequent
calls. Remove root_session_id from TracerConfig/FinalizedTracerConfig
— the singleton is now the sole source of truth, read directly in
Tracer construction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add root_session_id singleton test
Verify get_or_init returns the first runtime ID on subsequent calls
with different values (first-writer-wins semantics).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: move get_or_init into TracerSignature 3-param constructor
The 3-param constructor now calls root_session_id::get_or_init internally,
so every TracerSignature construction via the short form goes through the
singleton. Tracer no longer needs to call get_or_init directly.
Session header tests use the 4-param constructor to control values
directly without depending on singleton state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: fix fork test to compare against actual singleton value
The singleton may already be set from a prior test case. Compare
the child's result against what get_or_init actually returned,
not the runtime ID passed in this test.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: acquire root_session_id from singleton in session header tests
Use root_session_id::get_or_init to acquire the root session ID and
use it throughout the session header test cases.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* revert: move get_or_init back to tracer.cpp, remove tracer_signature.cpp
Keep the 3-param TracerSignature constructor as a simple inline
delegating constructor. The get_or_init call stays in tracer.cpp
where the Tracer is constructed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: fix clang-format violations in test files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: remove test_root_session_id.cpp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: remove unnecessary comments
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address review feedback
- Simplify singleton to static const Meyer's pattern, remove .cpp file
- Use C++17 compound namespaces in root_session_id.h
- Rename sig -> signature in telemetry_impl.cpp
- Remove singleton usage from tests, use 3-param constructor for match
- Add blank lines between constructors in tracer_signature.h
- Fix extra spaces in test Telemetry init alignment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove extra spaces in test Telemetry init alignment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: restore clang-format alignment in test_telemetry.cpp
clang-format requires the extra spaces for argument alignment.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: rename sig to tracer_signature to fix clang-format alignment
Using the longer variable name avoids clang-format's column alignment
padding while matching the naming convention in the rest of the file.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: re-add root_session_id to TracerConfig for integration seeding
Integrations (nginx, httpd, kong) need to set root_session_id in the
master process before workers fork. The Tracer passes it to get_or_init,
falling back to runtime_id if not provided.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: match field order in TracerConfig/FinalizedTracerConfig, remove redundant if checks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Zach Montoya <zach.montoya@datadoghq.com>1 parent 967246f commit 92cdfe6
File tree
10 files changed
+123
-14
lines changed- include/datadog
- src/datadog
- telemetry
- test
- mocks
- telemetry
10 files changed
+123
-14
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| 48 | + | |
48 | 49 | | |
49 | 50 | | |
50 | 51 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
189 | 189 | | |
190 | 190 | | |
191 | 191 | | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
192 | 197 | | |
193 | 198 | | |
194 | 199 | | |
| |||
225 | 230 | | |
226 | 231 | | |
227 | 232 | | |
| 233 | + | |
228 | 234 | | |
229 | 235 | | |
230 | 236 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
47 | 57 | | |
48 | 58 | | |
49 | 59 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
63 | 72 | | |
64 | 73 | | |
65 | 74 | | |
| |||
309 | 318 | | |
310 | 319 | | |
311 | 320 | | |
312 | | - | |
| 321 | + | |
| 322 | + | |
313 | 323 | | |
314 | 324 | | |
315 | 325 | | |
316 | 326 | | |
317 | 327 | | |
318 | 328 | | |
| 329 | + | |
319 | 330 | | |
320 | 331 | | |
321 | 332 | | |
| |||
363 | 374 | | |
364 | 375 | | |
365 | 376 | | |
366 | | - | |
367 | | - | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
368 | 380 | | |
369 | 381 | | |
370 | 382 | | |
371 | 383 | | |
372 | 384 | | |
373 | 385 | | |
| 386 | + | |
374 | 387 | | |
375 | 388 | | |
376 | 389 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| |||
48 | 49 | | |
49 | 50 | | |
50 | 51 | | |
51 | | - | |
52 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
53 | 56 | | |
54 | 57 | | |
55 | 58 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
403 | 403 | | |
404 | 404 | | |
405 | 405 | | |
406 | | - | |
407 | | - | |
408 | | - | |
409 | | - | |
| 406 | + | |
| 407 | + | |
410 | 408 | | |
411 | 409 | | |
412 | 410 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
44 | | - | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
45 | 48 | | |
46 | 49 | | |
47 | 50 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
366 | 366 | | |
367 | 367 | | |
368 | 368 | | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
369 | 430 | | |
370 | 431 | | |
371 | 432 | | |
| |||
0 commit comments