Skip to content

feat(otel): capture OTEL_CONFIG_WHITELIST vars with SDK-sourced type/default#4005

Draft
bm1549 wants to merge 1 commit into
masterfrom
brian.marks/otel-headers-supported-config
Draft

feat(otel): capture OTEL_CONFIG_WHITELIST vars with SDK-sourced type/default#4005
bm1549 wants to merge 1 commit into
masterfrom
brian.marks/otel-headers-supported-config

Conversation

@bm1549

@bm1549 bm1549 commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Description

The supported-configurations.json generator only captured OTEL_* env vars that the C extension reads via ZAI_STRL(), so SDK-owned configs like OTEL_EXPORTER_OTLP_HEADERS were never published. This PR fixes that and makes the published type/default for every OTEL config accurate.

  • Scrape the OTEL_CONFIG_WHITELIST array in src/DDTrace/OpenTelemetry/Configuration.php as an additional source (scoped to the array literal so unrelated OTEL_ mentions elsewhere in the file can't leak in), and add that file to the generator's input manifest.
  • Source type and default for each OTEL config by reflecting the OpenTelemetry PHP SDK's ValueTypes/Defaults interfaces, rather than publishing everything as string/"". These vars are resolved by the SDK, not the extension. The SDK is pinned in a dedicated, minimal composer context (tooling/otel-sdk, open-telemetry/sdk 1.14.0, committed lock) so generation is reproducible; the generator installs it on demand and reads only the constant-bearing interface files, not the Composer autoloader (whose bootstrap reads ambient OTEL_* env).
  • Type mapping: SDK integer→int, list→array, map→map, enum/mixed→string, float/ratio→decimal, bool→boolean. Per-signal OTLP vars (e.g. *_LOGS_*) inherit their generic counterpart, matching how the SDK resolves them. Real extension configs (e.g. OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) keep their authoritative extension default.

Defaults are the SDK's values; note that DatadogResolver overrides some at runtime (e.g. metrics temporality → delta).

The Configuration Consistency CI job (which regenerates from the pinned SDK and fails on drift) passes. The validate_supported_configurations_v2_local_file job will be red until the matching versions are added to the Feature Parity configuration registry, which is handled separately.

Reviewer checklist

  • Test coverage seems ok.
  • Appropriate labels assigned.

🤖 Generated with Claude Code

…default

The supported-configurations.json generator only scraped OTEL env vars that
the C extension reads via ZAI_STRL(), so SDK-owned configs such as
OTEL_EXPORTER_OTLP_HEADERS were never published. Scrape the
OTEL_CONFIG_WHITELIST array in src/DDTrace/OpenTelemetry/Configuration.php as
an additional source (scoped to the array literal so unrelated OTEL_ mentions
can't leak in) and add that file to the input manifest.

These OTEL vars are resolved by the open-telemetry/sdk PHP package, not the
extension, so publishing them all as string/"" was inaccurate. Source their
type and default by reflecting the SDK's ValueTypes/Defaults interfaces from a
pinned, dedicated composer context (tooling/otel-sdk, open-telemetry/sdk
1.14.0, committed lock for reproducibility). The generator installs that
context on demand and reads only the constant-bearing interface files (not the
Composer autoloader, whose bootstrap reads ambient OTEL_* env). SDK types map
to schema types (integer->int, list->array, map->map, enum/mixed->string,
float/ratio->decimal, bool->boolean); per-signal OTLP vars inherit their
generic counterpart. Applied to all OTEL entries; implementation labels and
real extension-config defaults (e.g. OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) are
preserved.

Note: defaults are the SDK's values; DatadogResolver overrides some at runtime
(e.g. metrics temporality -> delta).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bm1549 bm1549 added the AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos label Jun 22, 2026
@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Jun 22, 2026

Copy link
Copy Markdown

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 15 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-php | appsec integration tests: [test8.4-release]   View in Datadog   GitLab

🧪 1 Test failed

All test failures are known flaky.

❄️ Known flaky: extended heartbeat re-emits configuration, dependencies and integrations() from com.datadog.appsec.php.integration.TelemetryExtendedHeartbeatTests   View in Datadog
java.lang.AssertionError: phpredis not emitted via app-started/app-integrations-change; saw: []. Expression: (phpredis in flushed). Values: flushed = []

java.lang.AssertionError: phpredis not emitted via app-started/app-integrations-change; saw: []. Expression: (phpredis in flushed). Values: flushed = []
	at org.codehaus.groovy.runtime.InvokerHelper.createAssertError(InvokerHelper.java:416)
	at com.datadog.appsec.php.integration.TelemetryExtendedHeartbeatTests.extended heartbeat re-emits configuration, dependencies and integrations(TelemetryExtendedHeartbeatTests.groovy:70)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Not introduced in this PR.

DataDog/apm-reliability/dd-trace-php | pecl tests: [7.4]   View in Datadog   GitLab

DataDog/apm-reliability/dd-trace-php | test_extension_ci: [7.0]   View in Datadog   GitLab

View all 15 failed jobs.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 54.08% (+0.00%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 3e51f42 | Docs | Datadog PR Page | Give us feedback!

Comment on lines +313 to +324
// Type and default for OTEL configs, read by reflection from the pinned
// open-telemetry/sdk package (ValueTypes/Defaults interfaces) rather than the
// extension, which only observes these vars. SDK enum/mixed map to the schema's
// "string", list -> "array", map -> "map", integer -> "int", float/ratio ->
// "decimal", bool -> "boolean"; per the schema every default is a string, and
// map defaults are "". Per-signal OTLP exporter vars (e.g. *_LOGS_*) absent from
// ValueTypes inherit their generic OTEL_EXPORTER_OTLP_* counterpart, matching
// how the SDK resolves them. Defaults are the SDK's values; DatadogResolver
// overrides some at runtime (e.g. metrics temporality -> "delta").
// Require only the constant-bearing interface files, not the Composer autoloader:
// the SDK's autoload "files" run bootstrap code that reads ambient OTEL_* env,
// which must not influence (or break) metadata generation. VariableTypes first,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered two solutions here

  1. Keeping string / "" - discarded since this isn't what the underlying OTel SDK uses so it made the docs slightly incorrect
  2. Doing a one-time update of all of the config types/defaults - discarded since this would cause drift over time which we may not be aware of

Ultimately, this weird logic is isolated to a shell script, so it felt like an acceptable "lesser evil" so to say

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant