Coverage for /usr/local/lib/python3.10/site-packages/opal_common-0.0.0-py3.10.egg/opal_common/monitoring/apm.py: 42%
33 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 11:54 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 11:54 +0000
1import logging
2from urllib.parse import urlparse
4from ddtrace import patch, tracer
5from ddtrace.trace import TraceFilter
6from loguru import logger
9class DropRootPathTraces(TraceFilter):
10 """TraceFilter that drops any trace whose root HTTP route/path is "/".
12 Per ddtrace docs:
13 - process_trace receives a list of spans (one trace)
14 - return None to drop it, or the (optionally modified) list to keep it
15 We examine only the root span (parent_id is None).
16 """
18 def process_trace(self, trace):
19 # Locate root span
20 root = next((s for s in trace if getattr(s, "parent_id", None) is None), None)
21 if root is None:
22 return trace # Keep if we can't identify a root
24 # Prefer normalized route (framework-provided)
25 route = root.get_tag("http.route")
26 if route == "/":
27 return None
29 # Fallback: parse raw URL if present
30 url = root.get_tag("http.url")
31 if url:
32 try:
33 if urlparse(url).path == "/":
34 return None
35 except Exception:
36 # Fail-open: keep the trace if parsing fails
37 pass
39 return trace
42def configure_apm(enable_apm: bool, service_name: str):
43 """Enable Datadog APM and install the DropRootPathTraces filter."""
44 if not enable_apm: 44 ↛ 48line 44 didn't jump to line 48 because the condition on line 44 was always true
45 logger.info("Datadog APM disabled")
46 return
48 logger.info("Enabling Datadog APM")
50 patch(
51 fastapi=True,
52 redis=True,
53 asyncpg=True,
54 aiohttp=True,
55 loguru=True,
56 )
58 tracer.configure(
59 trace_processors=[DropRootPathTraces()],
60 )
63def fix_ddtrace_logging():
64 """Reduce ddtrace logger verbosity and remove its handlers so our logging
65 setup controls output."""
66 logging.getLogger("ddtrace").setLevel(logging.WARNING)
67 ddtrace_logger = logging.getLogger("ddtrace")
68 for handler in list(ddtrace_logger.handlers):
69 ddtrace_logger.removeHandler(handler)