log_config.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import logging
  2. import logging.handlers
  3. import json
  4. import sys
  5. import os
  6. from datetime import datetime, timezone
  7. class JsonFormatter(logging.Formatter):
  8. """JSON 日志格式化器 (适合生产环境日志聚合)"""
  9. def format(self, record: logging.LogRecord) -> str:
  10. log_entry = {
  11. "timestamp": datetime.now(timezone.utc).isoformat(),
  12. "level": record.levelname,
  13. "logger": record.name,
  14. "message": record.getMessage(),
  15. }
  16. if hasattr(record, "trace_id"):
  17. log_entry["trace_id"] = record.trace_id
  18. if record.exc_info and record.exc_info[0]:
  19. log_entry["exception"] = self.formatException(record.exc_info)
  20. return json.dumps(log_entry, ensure_ascii=False)
  21. def setup_logging(level: str = "INFO", json_format: bool = False):
  22. root = logging.getLogger()
  23. root.setLevel(getattr(logging, level.upper(), logging.INFO))
  24. root.handlers.clear()
  25. # 控制台 handler
  26. console_handler = logging.StreamHandler(sys.stdout)
  27. if json_format:
  28. console_handler.setFormatter(JsonFormatter())
  29. else:
  30. console_handler.setFormatter(logging.Formatter(
  31. "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
  32. datefmt="%Y-%m-%d %H:%M:%S",
  33. ))
  34. root.addHandler(console_handler)
  35. # 可选:文件落盘 (LOG_FILE 环境变量指定路径,默认不开启)
  36. log_file = os.getenv("LOG_FILE")
  37. if log_file:
  38. file_handler = logging.handlers.RotatingFileHandler(
  39. log_file, maxBytes=10 * 1024 * 1024, backupCount=5, encoding="utf-8"
  40. )
  41. file_handler.setFormatter(JsonFormatter())
  42. root.addHandler(file_handler)
  43. logging.getLogger("httpx").setLevel(logging.WARNING)
  44. logging.getLogger("chromadb").setLevel(logging.WARNING)
  45. logging.getLogger("langchain").setLevel(logging.WARNING)