Make a Langfuse trace worth opening: question, answer, session, no probe noise

This commit is contained in:
2026-08-21 14:45:32 +07:00
parent 53582b6030
commit f3eaab0948
16 changed files with 733 additions and 5 deletions
+27
View File
@@ -7,6 +7,7 @@ thread-pool endpoint.
"""
from __future__ import annotations
import base64
import re
import uuid
from contextlib import contextmanager
@@ -75,11 +76,37 @@ def configure_telemetry(settings: Any, metrics: Metrics | None = None) -> bool:
)
exporter = OTLPSpanExporter(endpoint=settings.otel_exporter_otlp_endpoint)
provider.add_span_processor(BatchSpanProcessor(exporter))
for extra in _langfuse_exporters(settings, OTLPSpanExporter):
provider.add_span_processor(BatchSpanProcessor(extra))
otel_trace.set_tracer_provider(provider)
_tracer = provider.get_tracer("duocthu.ai-service")
return True
def _langfuse_exporters(settings: Any, exporter_cls: Any) -> list[Any]:
"""Zero or one extra OTLP exporter pointed at Langfuse.
Langfuse accepts standard OTLP/HTTP on `/api/public/otel/v1/traces`,
authenticated with HTTP Basic using the project's public key as the
username and the secret key as the password. Returning a list keeps the
caller unchanged when Langfuse is not configured -- which is the default,
and the case for every local run without a `.env`.
"""
base_url = str(getattr(settings, "langfuse_base_url", "") or "").rstrip("/")
public_key = str(getattr(settings, "langfuse_public_key", "") or "")
secret_key = str(getattr(settings, "langfuse_secret_key", "") or "")
if not (base_url and public_key and secret_key):
return []
token = base64.b64encode(f"{public_key}:{secret_key}".encode()).decode()
return [
exporter_cls(
endpoint=f"{base_url}/api/public/otel/v1/traces",
headers={"Authorization": f"Basic {token}"},
)
]
def normalize_correlation_id(candidate: str | None) -> str:
value = (candidate or "").strip()
return value if _SAFE_CORRELATION.fullmatch(value) else str(uuid.uuid4())