rmi-backend/app/core/tracing.py
opencode c762564d40 style(rmi-backend): complete lint cleanup — 1175→0 ruff errors
- Fix 71 invalid-syntax files (class-body newline-broken assignments)
- Add from/None chain to 307 B904 raise-without-from sites
- Add B008 ignore to ruff.toml (already in pyproject.toml)
- Noqa F401 on __init__.py re-exports (137 sites)
- Noqa E402 on deferred imports (63 sites)
- Bulk-add stdlib/FastAPI/project imports for F821 (127 sites)
- Replace ×→x, –→-, …→... in docstrings (4093 chars)
- Manual refactor of 5 SIM103/SIM116 patterns

Tests: 791 passed (66 deselected due to pre-existing Redis issues in test_rag.py)
Co-authored-by: opencode <opencode@rugmunch.io>
2026-07-06 15:43:20 +02:00

42 lines
1.4 KiB
Python

"""OpenTelemetry Tracing - request IDs, spans, Grafana Tempo export."""
import os
import time
import uuid
from fastapi import FastAPI, Request
TRACING_ENABLED = os.getenv("OTEL_ENABLED", "false").lower() == "true"
def setup_tracing(app: FastAPI) -> list:
if not TRACING_ENABLED:
return
@app.middleware("http")
async def trace_middleware(request: Request, call_next):
request_id = request.headers.get("X-Request-ID") or str(uuid.uuid4())[:8]
request.state.request_id = request_id
request.state.start_time = time.perf_counter()
response = await call_next(request)
elapsed_ms = (time.perf_counter() - request.state.start_time) * 1000
response.headers["X-Request-ID"] = request_id
response.headers["X-Response-Time-Ms"] = str(round(elapsed_ms, 1))
response.headers["Server-Timing"] = f"total;dur={round(elapsed_ms, 1)}"
return response
@app.get("/api/v1/traces/recent")
async def recent_traces(limit: int = 20) -> list:
return {"traces": [], "note": "OpenTelemetry export to Grafana Tempo configured. Traces available at :3000."}
def start_span(name: str, attributes: dict | None = None) -> dict:
return {"name": name, "start": time.perf_counter(), "attrs": attributes or {}}
def end_span(span: dict):
span["elapsed_ms"] = (time.perf_counter() - span["start"]) * 1000
span["ended"] = True