Report OTLP export status in tracer startup log#12062
Conversation
Report whether the tracer exports each telemetry signal over OTLP in the "DATADOG TRACER CONFIGURATION" startup log via three boolean fields: otlp_traces_export_enabled, otlp_metrics_export_enabled, and otlp_logs_export_enabled. Metrics and logs require both the OTel signal to be enabled and the OTLP exporter to be selected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
There was a problem hiding this comment.
More details
The startup log fields match the runtime activation rules: traces follow OTLP exporter selection, while metrics and logs require both their OTel signal and OTLP exporter to be enabled. Alternate exporters, mixed signal states, and case variations are handled by the existing accessors; no diff-only behavioral regression was identified.
🤖 Datadog Autotest · Commit a4287c5 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a4287c54a9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Report otlp_traces_export_enabled from the resolved writer type (OtlpWriter) rather than the OTLP exporter selection, since an explicit dd.writer.type override wins over dd.trace.otel.exporter=otlp in WriterFactory. Also report otlp_metrics_export_enabled when client-side span metrics are enabled, since those are exported over OTLP via OtlpStatsMetricWriter independently of the OTel metrics signal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PerfectSlayer
left a comment
There was a problem hiding this comment.
Minor comments about style
Move the three derived booleans out of StatusLogger.toJson and into Config accessors: isOtlpTracesExportEnabled, isOtlpMetricsExportEnabled, and isOtlpLogsExportEnabled. Every other field toJson emits forwards a Config getter, so keeping the conjunctions inline made this method the only place in the file that derives a value it writes. Fix otlp_traces_export_enabled. It compared dd.writer.type to OtlpWriter for equality, so MultiWriter:OtlpWriter,DDAgentWriter reported false even though WriterFactory builds a real OtlpWriter for it. isOtlpTracesExportEnabled now mirrors WriterFactory's dispatch: a writer type that does not start with MultiWriter is compared to OtlpWriter directly, and one that does has every literal MultiWriter: removed before the remainder is split on commas and each sub-type compared. Removing every occurrence rather than a single leading prefix matches what MultiWriter itself does, so a repeated prefix such as MultiWriter:DDAgentWriter,MultiWriter:OtlpWriter resolves the same way in both places. Drop the two comment blocks in StatusLogger explaining writer precedence and span-metrics routing, and the three in StatusLoggerTest. StatusLogger carries no comments anywhere else, and the reasoning belongs in the commit message and pull request, which both record it. Expand StatusLoggerTest to 13 tests and assert with assertFalse and assertTrue instead of assertEquals against boolean literals. The new cases pin the writer type grammar: a MultiWriter list that includes OtlpWriter, one that excludes it, a repeated MultiWriter prefix, a padded sub-type, a sub-type that only prefixes OtlpWriter, a comma-separated list without the MultiWriter prefix, and a TraceStructureWriter value that WriterFactory dispatches before it ever reaches the MultiWriter branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
What Does This Do
Adds three boolean fields to the
DATADOG TRACER CONFIGURATIONstartup log emitted bydd-trace-core'sStatusLogger:otlp_traces_export_enabledConfig.isOtlpTracesExportEnabled()WriterFactorybuilds is anOtlpWriter, including when it is one of aMultiWriter's sub-writersotlp_metrics_export_enabledConfig.isOtlpMetricsExportEnabled()(isMetricsOtelEnabled() && isMetricsOtlpExporterEnabled()) || isOtelTracesSpanMetricsEnabled()otlp_logs_export_enabledConfig.isOtlpLogsExportEnabled()isLogsOtelEnabled() && isLogsOtlpExporterEnabled()The three accessors live on
Configrather than inline inStatusLogger.toJson, which forwards aConfiggetter for every one of its other fields.StatusLoggerTestis new. Its 13 tests cover the default disabled case, the fully-enabled case, the case where the OTLP exporter is selected but the metrics and logs OTel signals stay disabled, both routes to metrics export, and seven writer-type values that pin which ones do and do not resolve to anOtlpWriter.Motivation
Part of a cross-tracer effort to report OTLP export status in each tracer's startup log. The JSON keys are identical across the dd-trace-* libraries so the fields can be read the same way regardless of language.
Additional Notes
The traces field cannot read
dd.trace.otel.exporteralone.dd.writer.typetakes precedence over it, andWriterFactoryresolves that value through an ordered dispatch that can produce anOtlpWriternested inside aMultiWriter.isOtlpTracesExportEnabledmirrors that dispatch instead of comparing the raw setting, so the flag reports what the tracer actually built.Metrics export has two independent triggers: the OTel metrics signal paired with the OTLP exporter, or
dd.trace.otel.span.metrics.enabled, which routes span metrics over OTLP on its own.Three things I'd like your take on:
isTraceOtlpExporterEnabledand friends. Naming them after the keys keeps the startup-log contract greppable, but it is a judgment call and I would take a different convention if you prefer one.isOtlpTracesExportEnabledre-implements theMultiWriter:a,bgrammar thatMultiWriterparses. Extracting a shared parser both could use is the cleaner end state; I left it out because it would change trace-writer construction for the sake of a diagnostic flag. Happy to do it in a follow-up.MultiWriter:MultiWriMultiWriter:ter:OtlpWriter, still under-reports, becauseMultiWriterre-parses at every nesting level while this accessor parses once. Matching it exactly needs either a fixpoint loop or the same unbounded recursionMultiWriterhas, and no reachable configuration produces such a value, so I left the single pass in place.This is a diagnostic logging change and does not alter tracer runtime behavior.
Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issueRelated PRs — cross-tracer OTLP startup-log effort