chore(flask): emit pre-request web event - #19779
Conversation
This comment has been minimized.
This comment has been minimized.
Dependency direction analysis
|
| # make a request tracing function | ||
| def trace_tween(request): | ||
| core.dispatch(core.WEB_REQUEST_STARTING, (request.method, request.path)) | ||
|
|
There was a problem hiding this comment.
We made this change to allow emit WEB_REQUEST_STARTING event regardless of enabled or not
BenchmarksBenchmark execution time: 2026-08-23 21:15:56 Comparing candidate commit 55acf22 in PR branch Found 0 performance improvements and 10 performance regressions! Performance is the same for 607 metrics, 10 unstable metrics.
|
There was a problem hiding this comment.
Pull request overview
This PR introduces a new core event (core.WEB_REQUEST_STARTING) intended to be emitted by web entry points as soon as HTTP method/path are known, but before request context/root span creation, enabling early observers (e.g., MicroVM lifecycle detection) across disparate server stacks.
Changes:
- Added
WEB_REQUEST_STARTINGtoddtrace.internal.coreand emitted it from multiple supported web integrations (WSGI/ASGI/framework-specific) prior to request tracing. - Added a new
http_servercontrib integration that patcheshttp.server.BaseHTTPRequestHandler.parse_request()to emit the event for “raw stdlib server” use cases. - Added per-integration tests asserting the event is emitted (including on unmatched routes where applicable), plus integration registry / suite wiring for
http_server.
Reviewed changes
Copilot reviewed 39 out of 40 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/contrib/tornado/test_microvm_identity_refresh.py | New test coverage asserting Tornado emits the pre-request event with method/path. |
| tests/contrib/suitespec.yml | Adds http_server component + suite selection wiring for contrib test runs. |
| tests/contrib/sanic/test_sanic.py | Adds assertions that Sanic emits the pre-request event before tracing starts. |
| tests/contrib/pyramid/test_microvm_identity_refresh.py | New Pyramid tests covering event emission (including tracing-disabled behavior). |
| tests/contrib/molten/test_microvm_identity_refresh.py | New Molten tests asserting event emission from the WSGI entry point. |
| tests/contrib/http_server/test_microvm_identity_refresh.py | New tests validating http.server parse_request emits event only for well-formed requests. |
| tests/contrib/http_server/test_http_server_patch.py | Patch/unpatch/get_version coverage for the new http_server integration. |
| tests/contrib/http_server/init.py | Establishes the contrib test package for http_server. |
| tests/contrib/flask/test_microvm_identity_refresh.py | New Flask tests asserting event emission ordering (incl. before WSGI middleware). |
| tests/contrib/falcon/test_microvm_identity_refresh.py | New Falcon middleware tests asserting event emission on 404 and normal routes. |
| tests/contrib/django/test_microvm_identity_refresh.py | New Django tests asserting event emission before URL resolution. |
| tests/contrib/cherrypy/test_microvm_identity_refresh.py | New CherryPy tests asserting event emission at request start hook. |
| tests/contrib/bottle/test_microvm_identity_refresh.py | New Bottle tests asserting event emission at WSGI entry point. |
| tests/contrib/asgi/test_microvm_identity_refresh.py | New ASGI middleware tests asserting event emission and sub-app suppression behavior. |
| supported-configurations.json | Registers DD_TRACE_HTTP_SERVER_ENABLED and DD_HTTP_SERVER_SERVICE in the configuration registry. |
| scripts/integration_registry/registry.yaml | Registers http_server as a tested, internal integration. |
| riotfile.py | Adds a dedicated http_server riot venv target for contrib tests. |
| docs/integrations.rst | Adds http_server to the integrations documentation index. |
| ddtrace/internal/settings/_supported_configurations.py | Regenerated supported configuration list/aliases to include new keys. |
| ddtrace/internal/core/init.py | Defines the WEB_REQUEST_STARTING event constant. |
| ddtrace/contrib/internal/tornado/handlers.py | Emits WEB_REQUEST_STARTING at Tornado request execution start. |
| ddtrace/contrib/internal/sanic/patch.py | Emits WEB_REQUEST_STARTING at the shared Sanic request-span entry point. |
| ddtrace/contrib/internal/pyramid/trace.py | Refactors tween to always emit WEB_REQUEST_STARTING (even if tracing disabled) before tracing context. |
| ddtrace/contrib/internal/molten/patch.py | Emits WEB_REQUEST_STARTING at Molten’s WSGI entry wrapper. |
| ddtrace/contrib/internal/http_server/patch.py | New integration patching parse_request() to emit WEB_REQUEST_STARTING after successful parsing. |
| ddtrace/contrib/internal/http_server/init.py | New integration docstring describing the purpose and enabling/disabling behavior. |
| ddtrace/contrib/internal/flask/patch.py | Emits WEB_REQUEST_STARTING at the start of patched_wsgi_app(). |
| ddtrace/contrib/internal/falcon/middleware.py | Emits WEB_REQUEST_STARTING at the start of Falcon process_request(). |
| ddtrace/contrib/internal/django/response.py | Emits WEB_REQUEST_STARTING early in Django traced_get_response(). |
| ddtrace/contrib/internal/cherrypy/patch.py | Emits WEB_REQUEST_STARTING at CherryPy _on_start_resource(). |
| ddtrace/contrib/internal/bottle/trace.py | Adds a Bottle.wsgi wrapper emitting WEB_REQUEST_STARTING before routing. |
| ddtrace/contrib/internal/bottle/patch.py | Installs the new Bottle Bottle.wsgi wrapper. |
| ddtrace/contrib/internal/asgi/middleware.py | Emits WEB_REQUEST_STARTING for root-app HTTP requests before tracing context is created. |
| ddtrace/_monkey.py | Enables the new http_server integration by default and maps it to http.server. |
| .riot/requirements/43423a3.txt | Adds generated riot requirements lock for one environment set. |
| .riot/requirements/3cb8c3c.txt | Adds generated riot requirements lock for one environment set. |
| .riot/requirements/180047f.txt | Adds generated riot requirements lock for one environment set. |
| .riot/requirements/1638d0f.txt | Adds generated riot requirements lock for one environment set. |
| .riot/requirements/13ed954.txt | Adds generated riot requirements lock for one environment set. |
| .riot/requirements/1362718.txt | Adds generated riot requirements lock for one environment set. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| "DD_HTTP_SERVER_SERVICE": [ | ||
| { | ||
| "implementation": "A", | ||
| "type": "string", | ||
| "default": null, | ||
| "aliases": [ | ||
| "DD_HTTP_SERVER_SERVICE_NAME" | ||
| ] | ||
| } |
aac2ec3 to
2fa8088
Compare
c595b5b to
2724ad8
Compare
Codeowners resolved asResolved from the full PR diff against |
Circular import analysis
|
2df658b to
c0ad053
Compare
c0ad053 to
5022eba
Compare
@pr-commenter I ran the benchmark test locally for
Interpretation
Signals use the local guide thresholds: <2% is noise, 2-5% is small, and >5% regression should be investigated. Stddev overlap marks results that may need a rerun before drawing conclusions. |
5022eba to
92662ef
Compare
brettlangdon
left a comment
There was a problem hiding this comment.
it seems like http.server is a whole new integration, we should not bundle these together.
@brettlangdon Will do |
4c72681 to
4e70948
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e7094825c
ℹ️ 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".
There was a problem hiding this comment.
I'm not sure about the goal of this PR. There is already an existing web.request.start event. Can't we use this one ?
Additionally, right now, nothing is listening to this event so it is a bit hard to justify a full PR because it would mean we merge a noop/just overhead
| ROOT_CONTEXT_ID = "__root" | ||
| # Emitted by web integrations after method/path are available but before request | ||
| # context/root span creation, so listeners can update process-wide state first. | ||
| WEB_REQUEST_STARTING = "web.request.starting" |
There was a problem hiding this comment.
This is not the right place to define an event
There was a problem hiding this comment.
acked, it was moved to web_framework.py as i saw WEB_REQUEST defined there.
d4a3faa to
1cbc151
Compare
4e70948 to
55acf22
Compare
55acf22 to
d59e112
Compare
|
Renamed the branch to |
Description
The MicroVM
/runrequest has to be observed before a web root span reads runtime identity. This PR keeps the request-starting event coverage scoped to Flask.This adds a generic
WEB_REQUEST_STARTINGcore event and emits it from Flask once method and path are known, before request context/root span creation. The event is intentionally not tied to MicroVMs or runtime-id refresh in this PR.Testing
scripts/lint fmt ddtrace/internal/core/__init__.py ddtrace/contrib/internal/flask/patch.py tests/contrib/flask/test_microvm_identity_refresh.pyscripts/run-tests --venv e6872f6 tests/contrib/flask/test_microvm_identity_refresh.py -- -- -k microvm_identity_refreshRisks
Low. The event is emitted on Flask request entry, but it has no listener in this PR. The no-listener path should be cheap.
Release note
None. This PR adds an internal event emitter with no customer-visible listener. Use
changelog/no-changelog.Additional Notes
Depends on #19778. Follow-up PR adds stdlib
http.serversupport.