feat(acp): warn when ddtrace double-instruments the route handler#409
Closed
max-parke-scale wants to merge 1 commit into
Closed
feat(acp): warn when ddtrace double-instruments the route handler#409max-parke-scale wants to merge 1 commit into
max-parke-scale wants to merge 1 commit into
Conversation
A process with more than one ddtrace auto-instrumentation entry point (e.g. an in-agent ddtrace.patch_all()/ddtrace-run alongside Datadog single-step instrumentation) wraps the FastAPI/Starlette route handler twice. Each request then accumulates the route path twice, so ddtrace emits a doubled resource_name/http.route (POST /api/api, GET /healthz/healthz) while the served path is unchanged — silently blinding monitors filtered on the single-prefix resource_name. Add a best-effort startup check that counts ddtrace traced_handler wraps on the route handler and logs an actionable warning when it exceeds one, plus docs/observability.md documenting the single-entry-point rule and the path_group-based monitor filter that stays correct even when the resource name doubles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8328a52 to
cb71af4
Compare
Contributor
Author
|
Closing — this doesn't belong in the general agentex SDK. The incident (issue #3: ddtrace doubling the ACP route template → Why not land the guard + docs here:
No code change is warranted in this repo. Knowledge capture for the SGP side can ride with #1702 / the platform owners. 🧑💻🤖 — posted via Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue #3 (0.13.0 incident): ddtrace doubled the ACP route template in Datadog APM
On
centipede-student-assistant-agentex-agent, ddtrace'sresource_name/http.routedoubled the router prefix (POST /api/api,GET /healthz/healthz) alongside the correct single-prefix names. The served URL was unaffected (http.url,http.path_group,http.inferred_routestayed single), so traffic worked but monitors/dashboards filtered onresource_name:post_/apisilently lost the doubled fraction.Root cause
The ACP server registers single routes correctly — the doubling is ddtrace's. ddtrace's
traced_handlerwraps the inheritedAPIRoute.handle; when two independent ddtrace auto-instrumentation passes run in one process, their de-dupe guards (_datadog_patchflag,is_wrapted) don't cross-recognize each other and the handler is wrapped twice — so each request accumulates the route path twice. A single ddtrace never doubles (verified across 3.13.0→4.10.1 and the realddtrace-run/ddtrace.autolaunch paths); two entry points do.In the incident the two passes were an in-agent
ddtrace.patch_all()and the platform's Datadog single-step instrumentation (admission.datadoghq.com/enabled: "true"). The agent-side and monitor-side remediations are tracked separately; this PR is the SDK-side guard + guidance.What this changes
base_acp_server.py:_warn_if_double_instrumented()runs at lifespan startup, counts ddtracetraced_handlerwraps on the route handler, and logs an actionableWARNINGif >1. Best-effort — reads ddtrace/wrapt internals insidetry/except, returns 0 (silent) if ddtrace is inactive or internals shift. No behavior change beyond the log line.docs/observability.md: the single-entry-point rule (don't combinepatch_all()/ddtrace-runwith platform SSI), the symptom, the local-dev tradeoff, the floor-only-pin fragility, and the@http.path_group:/apimonitor filter that stays correct even when the resource name doubles.Verification
0(no ddtrace) →1(clean single instrument, no warning) →2(double-wrap, warning logged).ruff checkpasses; the diff is additive (+51/−0 in the server file), no reformatting churn.Files:
src/agentex/lib/sdk/fastacp/base/base_acp_server.py(+51),docs/observability.md(new, +51).🧑💻🤖 — posted via Claude Code