feat(c-binding): expose custom collector callback#310
feat(c-binding): expose custom collector callback#310adeshkumar1 wants to merge 1 commit intomainfrom
Conversation
|
@codex review |
BenchmarksBenchmark execution time: 2026-04-17 20:18:32 Comparing candidate commit 3cc9c15 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 1 metrics, 0 unstable metrics.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee1edb7346
ℹ️ 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".
| return; | ||
| } | ||
| cfg->collector = std::make_shared<CallbackCollector>(callback, user_data); | ||
| cfg->telemetry.enabled = false; |
There was a problem hiding this comment.
Override env telemetry when callback mode is enabled
Setting cfg->telemetry.enabled = false here does not reliably disable telemetry in callback mode, because telemetry finalization gives environment variables higher precedence (pick(env_config->enabled, user_config.enabled, true) in src/datadog/telemetry/configuration.cpp). In environments with DD_INSTRUMENTATION_TELEMETRY_ENABLED=true, the tracer will still start telemetry network traffic even after dd_tracer_conf_set_collector_callback, which breaks the documented "zero network I/O" behavior for this API.
Useful? React with 👍 / 👎.
|
🎯 Code Coverage (details) 🔗 Commit SHA: 3cc9c15 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback! |
ee1edb7 to
a6108c6
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6108c673f
ℹ️ 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".
|
|
||
| const auto *config = reinterpret_cast<const dd::TracerConfig *>(conf_handle); | ||
| const auto validated_config = dd::finalize_config(*config); | ||
| auto validated_config = dd::finalize_config(*config); |
There was a problem hiding this comment.
Bypass agent URL validation in callback collector mode
dd_tracer_new always runs finalize_config(*config) before handling the callback-collector path, so tracer creation still fails when DD_TRACE_AGENT_URL/DD_OPT_AGENT_URL is malformed even though traces are being diverted to the in-process callback. finalize_config validates agent config unconditionally (src/datadog/tracer_config.cpp), which makes this new callback mode unusable in callback-only deployments that intentionally do not rely on agent transport.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Documented as a caveat in the header docstring — malformed DD_TRACE_AGENT_URL / DD_OPT_AGENT_URL still fails finalize_config before the callback path is taken. Fixing this properly requires either unsetenv() (process-wide side effect) or refactoring finalize_config to defer agent validation, both of which are out of scope for this PR. Callers in callback mode should simply not set a malformed URL.
| validated_config->telemetry.enabled = false; | ||
| validated_config->telemetry.report_metrics = false; | ||
| validated_config->telemetry.report_logs = false; |
There was a problem hiding this comment.
Disable telemetry globally when callback collector is used
This only mutates the local tracer config, but telemetry is process-global and initialized once (src/datadog/telemetry/telemetry.cpp uses a static singleton), so if another tracer already initialized telemetry as enabled, creating a callback-configured tracer here will not actually stop telemetry network traffic. In multi-tracer processes, this violates the new API contract that callback mode performs zero network I/O.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Documented as a caveat in the header docstring. Telemetry is process-global; the config setter can only affect this tracer's finalized config. In multi-tracer processes where an earlier tracer already initialized telemetry as enabled, that traffic continues. Fully silencing it from the C binding would require touching the telemetry module's singleton, which is out of scope. The typical C-binding use case (Kong) is single-tracer-per-process, where this is a non-issue.
|
@codex review |
a6108c6 to
5f810b7
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5f810b75d8
ℹ️ 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".
| // In callback mode the agent URL is never contacted. Clear any user-set | ||
| // value so finalize_config's agent URL validation uses the internal | ||
| // default and doesn't fail on a malformed DD_OPT_AGENT_URL. | ||
| cfg->agent.url.reset(); |
There was a problem hiding this comment.
Preserve agent URL when clearing collector callback
Avoid mutating unrelated configuration when enabling the callback: this path unconditionally calls cfg->agent.url.reset(), but the clear path (callback == NULL) only resets collector. If a caller sets DD_OPT_AGENT_URL, enables the callback, and later clears it (which the API advertises as supported), the original agent URL is silently lost and subsequent tracers will send to the default endpoint instead of the configured one.
Useful? React with 👍 / 👎.
Add dd_tracer_conf_set_collector_callback so FFI callers can intercept finished trace chunks in-process instead of POSTing to an agent. The callback receives the exact msgpack bytes that /v0.4/traces would have served, produced by the same encoder the DatadogAgent uses (wrapped in a 1-element outer array to match the wire format). When a callback is installed, telemetry and remote-configuration polling are disabled automatically so the tracer performs zero network I/O — the whole point of installing a custom collector is not to depend on an agent. Motivated by the Kong plugin's integration test (spec/02-integration-tests/01-agent_spec.lua), which is currently pending because helpers.http_mock accepts only one connection and dd-trace-cpp's default transport opens two (telemetry first, then traces), so the traces assertion never fires. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@codex review |
5f810b7 to
3cc9c15
Compare
|
Codex Review: Didn't find any major issues. Chef's kiss. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Summary
Adds
dd_tracer_conf_set_collector_callback(handle, callback, user_data)so FFI callers can intercept finished trace chunks in-process instead of POSTing to an agent. The callback receives the exact msgpack bytes/v0.4/traceswould have served, produced by the same encoder theDatadogAgentuses (wrapped in a 1-element outer array to match the wire format).When a callback is installed, telemetry and remote-configuration polling are disabled automatically so the tracer performs zero network I/O.
Motivation
The Kong plugin's integration test (
spec/02-integration-tests/01-agent_spec.lua) is currently pending becausehelpers.http_mockaccepts one connection but dd-trace-cpp opens two (telemetry first, then traces). This callback lets the test intercept traces in-process with no HTTP mock.Notes
sendis invoked synchronously on the thread finishing each span. Blocking in the callback stalls span finishing on that thread.user_datamust outlive the tracer (the callback may fire duringdd_tracer_freeas pending spans auto-finish).callback == NULLclears the collector but does not re-enable them.Test plan
./build-c/test/tests \"[c_binding]\"— 11 cases / 58 assertionsbin/check-format01-agent_spec.luaoff pending, confirm it passes with no HTTP mock🤖 Generated with Claude Code