mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-18 18:15:09 +00:00
Add the per-request trace recorder
docsgpt.tracing records agent, LLM, tool, retrieval and embedding spans in memory and writes the finished trace once. Container spans nest by a per-thread stack so suspended generators cannot corrupt the tree; open spans are cancelled at flush and previews are bounded and redacted.
This commit is contained in:
1 parent
f3f817b1e8
commit
3f45d019b0
6 files changed
+1124
No files matched your search
@@ -0,0 +1,53 @@
|
||||
"""Write a finished trace to its two sinks: Postgres and OpenTelemetry."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from docsgpt.tracing.core import Trace
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def flush(trace: Optional[Trace], status: Optional[str] = None) -> None:
|
||||
"""Finish ``trace`` and persist it once; later calls are no-ops.
|
||||
|
||||
OTel replay runs first so the exported trace id can be stored with the
|
||||
row. Both sinks swallow their own failures: a trace is diagnostic data
|
||||
and must never fail the request that produced it.
|
||||
|
||||
Args:
|
||||
trace: The trace to write; ``None`` is accepted and ignored.
|
||||
status: Final status; defaults to ``error`` when a top-level span
|
||||
failed, else ``ok``.
|
||||
"""
|
||||
if trace is None or trace.flushed:
|
||||
return
|
||||
trace.flushed = True
|
||||
trace.finish(status)
|
||||
try:
|
||||
from docsgpt.tracing.otel import export_trace
|
||||
|
||||
trace.otel_trace_id = export_trace(trace)
|
||||
except Exception: # noqa: BLE001
|
||||
logger.warning("Failed to export trace %s to OpenTelemetry", trace.id, exc_info=True)
|
||||
if not trace.spans:
|
||||
# Nothing ran worth showing (e.g. an early validation error).
|
||||
return
|
||||
try:
|
||||
from docsgpt.storage.db.repositories.request_traces import RequestTracesRepository
|
||||
from docsgpt.storage.db.session import db_session
|
||||
|
||||
with db_session() as conn:
|
||||
RequestTracesRepository(conn).insert(trace.to_record())
|
||||
except Exception: # noqa: BLE001
|
||||
logger.warning("Failed to store trace %s", trace.id, exc_info=True)
|
||||
|
||||
|
||||
def discard(trace: Optional[Trace]) -> None:
|
||||
"""Drop ``trace`` without writing it (the request was rejected or superseded)."""
|
||||
if trace is None or trace.flushed:
|
||||
return
|
||||
trace.flushed = True
|
||||
trace.finish()
|
||||
Reference in new issue
Block a user