70 lines
1.8 KiB
Python
70 lines
1.8 KiB
Python
import json
|
|
import logging
|
|
import time
|
|
from typing import Any, Optional
|
|
|
|
logger = logging.getLogger("app")
|
|
|
|
SCHEMA_VERSION = 1
|
|
|
|
|
|
def _normalize_value(value: Any) -> Any:
|
|
if value is None:
|
|
return None
|
|
if isinstance(value, (str, int, float, bool)):
|
|
return value
|
|
return str(value)
|
|
|
|
|
|
def emit_question_metric(
|
|
*,
|
|
stage: str,
|
|
status: str,
|
|
duration_ms: Optional[int] = None,
|
|
first_response_time_ms: Optional[int] = None,
|
|
trace_id: Optional[str] = None,
|
|
ai_id: Optional[str] = None,
|
|
session_id: Optional[str] = None,
|
|
robot_type: Optional[str] = None,
|
|
model: Optional[str] = None,
|
|
stream: Optional[bool] = None,
|
|
error_type: Optional[str] = None,
|
|
extra: Optional[dict[str, Any]] = None,
|
|
) -> None:
|
|
payload: dict[str, Any] = {
|
|
"schema_version": SCHEMA_VERSION,
|
|
"event": {
|
|
"kind": "metric",
|
|
"category": ["question"],
|
|
"action": "question_perf",
|
|
},
|
|
"stage": stage,
|
|
"status": status,
|
|
"observed_at": int(time.time() * 1000),
|
|
"service": "catalog-agent",
|
|
}
|
|
|
|
optional_fields = {
|
|
"trace_id": trace_id,
|
|
"duration_ms": duration_ms,
|
|
"first_response_time_ms": first_response_time_ms,
|
|
"ai_id": ai_id,
|
|
"session_id": session_id,
|
|
"robot_type": robot_type,
|
|
"model": model,
|
|
"stream": stream,
|
|
"error_type": error_type,
|
|
}
|
|
for key, value in optional_fields.items():
|
|
normalized = _normalize_value(value)
|
|
if normalized is not None:
|
|
payload[key] = normalized
|
|
|
|
if extra:
|
|
for key, value in extra.items():
|
|
normalized = _normalize_value(value)
|
|
if normalized is not None:
|
|
payload[key] = normalized
|
|
|
|
logger.info(json.dumps(payload, ensure_ascii=False, separators=(",", ":")))
|