Files
ai-shiliu/app/infrastructure/service/logging/log_schema.py

87 lines
2.2 KiB
Python
Raw Normal View History

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any
MODULES = {"api", "bot", "ocr", "ai", "db", "capture", "audit", "error"}
DOMAIN_MODULES = {"api", "bot", "ocr", "ai", "db", "capture"}
ALLOWED_EVENTS = {
"api.bot.status",
"api.bot.start",
"api.bot.stop",
"api.messages.receive",
"audit.decision",
"bot.chat_analyze",
"bot.chat_snapshot",
"bot.loop",
"bot.session_scan",
"bot.session_service.init",
"bot.session_title",
"bot.submit",
"bot.unread.detect",
"bot.unread.scan",
"ocr.baidu.token",
"ocr.baidu.recognize",
"ocr.rapid.init",
"ocr.rapid.recognize",
"ocr.fallback",
"ocr.session_name",
"ocr.session_title",
"ocr.generic",
"capture.contact_list",
"capture.session_title",
"capture.chat_area",
"ai.request",
"ai.response",
"db.init",
"db.error",
"db.rule.query",
"db.rule.match",
}
def normalize_event(module: str, event: str) -> str:
e = str(event or "").strip().lower()
m = str(module or "").strip().lower()
if e in ALLOWED_EVENTS:
return e
if "." in e:
prefix = e.split(".", 1)[0]
if prefix in DOMAIN_MODULES:
return e
if m in DOMAIN_MODULES:
return f"{m}.unknown"
return "api.unknown"
@dataclass
class LogEvent:
level: str
module: str
event: str
trace_id: str
stage: str
status: str
message: str
reason: str = ""
extra: dict[str, Any] = field(default_factory=dict)
ts: str = ""
def to_dict(self) -> dict[str, Any]:
ts = self.ts or datetime.now().astimezone().isoformat(timespec="milliseconds")
module = self.module if self.module in MODULES else "api"
event = normalize_event(module, self.event)
return {
"ts": ts,
"level": (self.level or "INFO").upper(),
"module": module,
"event": event,
"trace_id": self.trace_id or "-",
"stage": self.stage or "-",
"status": self.status or "ok",
"reason": self.reason or "",
"message": self.message or "",
"extra": self.extra or {},
}