appQQQ commited on
Commit
84beb12
·
verified ·
1 Parent(s): f0528cf

chore: upload app/core/logging.py

Browse files
Files changed (1) hide show
  1. app/core/logging.py +70 -0
app/core/logging.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """结构化日志 (JSON 格式, 便于 LangSmith 解析)."""
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ import sys
6
+ from typing import Any
7
+
8
+ from app.config import settings
9
+
10
+
11
+ class JSONFormatter(logging.Formatter):
12
+ """极简 JSON formatter — 生产用. 开发可切回默认."""
13
+
14
+ def format(self, record: logging.LogRecord) -> str:
15
+ import json
16
+
17
+ payload: dict[str, Any] = {
18
+ "ts": self.formatTime(record, self.datefmt),
19
+ "level": record.levelname,
20
+ "logger": record.name,
21
+ "msg": record.getMessage(),
22
+ }
23
+ if record.exc_info:
24
+ payload["exc"] = self.formatException(record.exc_info)
25
+ # 透传 extra 字段
26
+ for k, v in record.__dict__.items():
27
+ if k in (
28
+ "name", "msg", "args", "levelname", "levelno", "pathname",
29
+ "filename", "module", "exc_info", "exc_text", "stack_info",
30
+ "lineno", "funcName", "created", "msecs", "relativeCreated",
31
+ "thread", "threadName", "processName", "process", "message",
32
+ "taskName",
33
+ ):
34
+ continue
35
+ try:
36
+ json.dumps(v)
37
+ payload[k] = v
38
+ except (TypeError, ValueError):
39
+ payload[k] = str(v)
40
+ return json.dumps(payload, ensure_ascii=False)
41
+
42
+
43
+ def setup_logging() -> None:
44
+ """初始化根 logger. 在 lifespan 启动时调用."""
45
+ root = logging.getLogger()
46
+ root.setLevel(settings.log_level.upper())
47
+
48
+ # 避免重复 handler
49
+ if root.handlers:
50
+ return
51
+
52
+ handler = logging.StreamHandler(sys.stdout)
53
+ if settings.log_level.upper() == "DEBUG":
54
+ handler.setFormatter(
55
+ logging.Formatter(
56
+ "%(asctime)s | %(levelname)-7s | %(name)s | %(message)s",
57
+ datefmt="%H:%M:%S",
58
+ )
59
+ )
60
+ else:
61
+ handler.setFormatter(JSONFormatter())
62
+ root.addHandler(handler)
63
+
64
+ # 降噪第三方库
65
+ for noisy in ("httpx", "httpcore", "openai", "chromadb", "huggingface_hub"):
66
+ logging.getLogger(noisy).setLevel(logging.WARNING)
67
+
68
+
69
+ def get_logger(name: str) -> logging.Logger:
70
+ return logging.getLogger(name)