feat(trace): 在请求链路追踪中记录并展示首字时间(TTFB)

将 first_byte_time_ms 添加到候选记录的 extra_data 中,
并在前端时间线组件中展示该指标。
This commit is contained in:
fawney19
2026-01-14 16:41:58 +08:00
parent ec3c5994d9
commit 97d66a8d0c
3 changed files with 32 additions and 18 deletions

View File

@@ -1438,6 +1438,13 @@ class CliMessageHandlerBase(BaseMessageHandler):
if ctx.status_code and ctx.status_code >= 400:
# 请求链路追踪使用 upstream_response原始响应回退到 error_message友好消息
trace_error_message = ctx.upstream_response or ctx.error_message or f"HTTP {ctx.status_code}"
extra_data = {
"stream_completed": False,
"chunk_count": ctx.chunk_count,
"data_count": ctx.data_count,
}
if ctx.first_byte_time_ms is not None:
extra_data["first_byte_time_ms"] = ctx.first_byte_time_ms
RequestCandidateService.mark_candidate_failed(
db=bg_db,
candidate_id=ctx.attempt_id,
@@ -1447,23 +1454,22 @@ class CliMessageHandlerBase(BaseMessageHandler):
error_message=trace_error_message,
status_code=ctx.status_code,
latency_ms=response_time_ms,
extra_data={
"stream_completed": False,
"chunk_count": ctx.chunk_count,
"data_count": ctx.data_count,
},
extra_data=extra_data,
)
else:
extra_data = {
"stream_completed": True,
"chunk_count": ctx.chunk_count,
"data_count": ctx.data_count,
}
if ctx.first_byte_time_ms is not None:
extra_data["first_byte_time_ms"] = ctx.first_byte_time_ms
RequestCandidateService.mark_candidate_success(
db=bg_db,
candidate_id=ctx.attempt_id,
status_code=ctx.status_code,
latency_ms=response_time_ms,
extra_data={
"stream_completed": True,
"chunk_count": ctx.chunk_count,
"data_count": ctx.data_count,
},
extra_data=extra_data,
)
finally:

View File

@@ -241,16 +241,20 @@ class StreamTelemetryRecorder:
from src.services.request.candidate import RequestCandidateService
extra_data: Dict[str, Any] = {
"stream_completed": ctx.is_success(),
"data_count": ctx.data_count,
}
if ctx.first_byte_time_ms is not None:
extra_data["first_byte_time_ms"] = ctx.first_byte_time_ms
if ctx.is_success():
RequestCandidateService.mark_candidate_success(
db=db,
candidate_id=ctx.attempt_id,
status_code=ctx.status_code,
latency_ms=response_time_ms,
extra_data={
"stream_completed": True,
"data_count": ctx.data_count,
},
extra_data=extra_data,
)
else:
error_type = "client_disconnected" if ctx.status_code == 499 else "stream_error"
@@ -263,10 +267,7 @@ class StreamTelemetryRecorder:
error_message=trace_error_message,
status_code=ctx.status_code,
latency_ms=response_time_ms,
extra_data={
"stream_completed": False,
"data_count": ctx.data_count,
},
extra_data=extra_data,
)
async def _update_usage_status_on_error(