fix(langfuse): v4 가 옛 ingestion 을 거부 — OTLP/HTTP JSON(/api/public/otel/v1/traces)으로 전환, 로컬 Langfuse 실측 통과. 사용자·세션 속성은 자식 span 에도 복사

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
lee-hyeon-cheol
2026-09-22 13:53:20 +09:00
co-authored by Claude Fable 5.1
parent 0321050053
commit 55f2e8fb60
7 changed files with 175 additions and 68 deletions
+6 -3
View File
@@ -133,13 +133,16 @@ async def test_stream_reports_generation_to_langfuse(upstream, monkeypatch):
from apps.gateway import langfuse
got = []
monkeypatch.setattr(langfuse, "TRANSPORT", httpx.MockTransport(lambda r: (got.append(json.loads(r.content)), httpx.Response(207, json={}))[1]))
monkeypatch.setattr(langfuse, "TRANSPORT", httpx.MockTransport(lambda r: (got.append(json.loads(r.content)), httpx.Response(200, json={}))[1]))
upstream(lambda r: _sse(b'data: {"choices":[{"delta":{"content":"hi"}}],"usage":{"prompt_tokens":2,"completion_tokens":1}}\n\ndata: [DONE]\n\n'))
resp = await _post({"model": "581", "stream": True, "messages": [{"role": "user", "content": "q"}]})
b"".join([c async for c in resp.streaming_content])
await asyncio.gather(*list(langfuse._pending))
gen = got[0]["batch"][1]["body"]
assert gen["model"] == "581" and gen["output"] == "hi" and gen["usage"]["total"] == 3 and gen["input"][0]["content"] == "q"
spans = got[0]["resourceSpans"][0]["scopeSpans"][0]["spans"]
ga = {a["key"]: a["value"].get("stringValue") for a in spans[1]["attributes"]}
assert ga["langfuse.observation.model.name"] == "581" and ga["langfuse.observation.output"] == "hi"
assert json.loads(ga["langfuse.observation.usage_details"])["total"] == 3
assert json.loads(ga["langfuse.observation.input"])[0]["content"] == "q"
@override_settings(FABRIX_ENV=FULL_ENV)