85 lines
2.9 KiB
Python
85 lines
2.9 KiB
Python
"""
|
||
utils/logger.py
|
||
统一日志工具 —— 所有模块通过 get_logger(name) 获取 logger
|
||
日志级别、输出目录、文件名均来自 config.yaml logging 节
|
||
"""
|
||
|
||
import logging
|
||
import os
|
||
import sys
|
||
from logging.handlers import RotatingFileHandler
|
||
from pathlib import Path
|
||
|
||
# 避免循环导入:logger 初始化时不能 import settings
|
||
# 改为延迟读取,首次调用时从环境变量 / 默认值获取
|
||
_LOG_LEVEL_ENV = os.getenv("LOG_LEVEL", "DEBUG").upper()
|
||
_LOG_DIR_ENV = os.getenv("LOG_DIR", "./logs")
|
||
_LOG_FILE_ENV = os.getenv("LOG_FILE", "agent.log")
|
||
_ENABLE_FILE = os.getenv("LOG_FILE_ENABLE", "true").lower() == "true"
|
||
|
||
_FORMATTER = logging.Formatter(
|
||
fmt="%(asctime)s [%(levelname)-8s] %(name)-24s │ %(message)s",
|
||
datefmt="%Y-%m-%d %H:%M:%S",
|
||
)
|
||
|
||
# 全局 handler 缓存(避免重复添加)
|
||
_handlers_initialized: bool = False
|
||
_root_logger = logging.getLogger("agent")
|
||
|
||
|
||
def _init_handlers() -> None:
|
||
global _handlers_initialized
|
||
if _handlers_initialized:
|
||
return
|
||
|
||
# 尝试从 settings 读取配置(settings 已加载后才有效)
|
||
try:
|
||
from config.settings import settings
|
||
level = getattr(logging, settings.logging.level, logging.DEBUG)
|
||
log_dir = settings.logging.log_dir
|
||
log_file = settings.logging.log_file
|
||
enable_file= settings.logging.enable_file
|
||
except Exception:
|
||
level = getattr(logging, _LOG_LEVEL_ENV, logging.DEBUG)
|
||
log_dir = _LOG_DIR_ENV
|
||
log_file = _LOG_FILE_ENV
|
||
enable_file= _ENABLE_FILE
|
||
|
||
_root_logger.setLevel(level)
|
||
|
||
# ── 控制台 Handler ────────────────────────────────────────
|
||
if not any(isinstance(h, logging.StreamHandler) for h in _root_logger.handlers):
|
||
console_handler = logging.StreamHandler(sys.stdout)
|
||
console_handler.setFormatter(_FORMATTER)
|
||
console_handler.setLevel(level)
|
||
_root_logger.addHandler(console_handler)
|
||
|
||
# ── 文件 Handler(RotatingFile)──────────────────────────
|
||
if enable_file:
|
||
log_path = Path(log_dir)
|
||
log_path.mkdir(parents=True, exist_ok=True)
|
||
file_handler = RotatingFileHandler(
|
||
filename=log_path / log_file,
|
||
maxBytes=10 * 1024 * 1024, # 10 MB
|
||
backupCount=5,
|
||
encoding="utf-8",
|
||
)
|
||
file_handler.setFormatter(_FORMATTER)
|
||
file_handler.setLevel(level)
|
||
_root_logger.addHandler(file_handler)
|
||
|
||
_root_logger.propagate = False
|
||
_handlers_initialized = True
|
||
|
||
|
||
def get_logger(name: str) -> logging.Logger:
|
||
"""
|
||
获取命名 logger
|
||
|
||
用法:
|
||
logger = get_logger("MCP.SkillClient")
|
||
logger = get_logger("TOOL.StaticAnalyzer")
|
||
logger = get_logger("Agent")
|
||
"""
|
||
_init_handlers()
|
||
return logging.getLogger(f"agent.{name}") |