fix(tracing): capture request paths for unmatched routes
Build and Push Docker Container / build-and-push (push) Successful in 4m43s

- Record url.path before routing so 404s and early responses retain their path.
- Keep matched route templates as span names to limit cardinality.
- Exclude query strings, full URLs, cookies and authorization headers.
- Test decoded paths on 404 responses and path attributes on matched routes.
- Document that paths may expose filenames, IDs or share tokens.
- Validate NanoShare with 294 passing tests.
This commit is contained in:
2026-10-31 18:15:47 +01:00
parent bc44273155
commit aec9d2e317
3 changed files with 39 additions and 6 deletions
+8 -3
View File
@@ -1,4 +1,4 @@
"""HTTP request -> Convex client spans. No payload/header/URL capture."""
"""HTTP and Convex spans with request paths, but no query/header/payload capture."""
import asyncio
import os
@@ -32,7 +32,12 @@ class RequestTracingMiddleware:
f"HTTP {method}",
context=_PROPAGATOR.extract(carrier),
kind=SpanKind.SERVER,
attributes={"http.request.method": method},
attributes={
"http.request.method": method,
# ASGI path excludes the query string. Capture it before routing so
# unmatched requests and early middleware responses remain identifiable.
"url.path": scope.get("path", ""),
},
record_exception=False,
set_status_on_exception=False,
) as span:
@@ -93,7 +98,7 @@ def register_request_tracing(app, *, provider=None):
request_id = event.get("request_id")
if request_id:
span.set_attribute("request.id", request_id)
# Only the route template, not the raw path, query string or user values.
# Keep span names low-cardinality; the actual path is in url.path.
if request.url_rule is not None:
route = request.url_rule.rule
span.update_name(f"{request.method} {route}")