# +====================================================================== # | DjangoAdmin 企业数字化开发平台 [ 赋能开发者,助力企业发展 ] # +---------------------------------------------------------------------- # | Copyright (c) 2021-2026 一米阳光团队 版权所有 # | 开源协议: Apache-2.0 # +====================================================================== """结构化日志配置:控制台 + 文件双输出,日志文件位于 logs/ 目录。""" import logging import sys from pathlib import Path # 日志目录(项目根目录下 logs/) LOG_DIR = Path(__file__).resolve().parent.parent / "logs" LOG_DIR.mkdir(parents=True, exist_ok=True) _FORMAT = "%(asctime)s | %(levelname)-7s | %(name)s | %(message)s" def setup_logging(level: int = logging.INFO, log_file: str = "app.log") -> None: """ 配置全局日志:root logger 输出到控制台与文件。 Args: level: 日志级别 log_file: 日志文件名(位于 logs/ 目录下) """ root = logging.getLogger() # 避免重复添加 handler if any(getattr(h, '_djangoadmin', False) for h in root.handlers): return root.setLevel(level) formatter = logging.Formatter(_FORMAT) # 控制台 console = logging.StreamHandler(sys.stdout) console.setFormatter(formatter) console._djangoadmin = True # type: ignore[attr-defined] root.addHandler(console) # 文件 file_handler = logging.FileHandler(LOG_DIR / log_file, encoding="utf-8") file_handler.setFormatter(formatter) file_handler._djangoadmin = True # type: ignore[attr-defined] root.addHandler(file_handler) # uvicorn/fastapi 默认日志走同样 handler for name in ("uvicorn", "fastapi"): lg = logging.getLogger(name) lg.handlers.clear() lg.propagate = True