feat: 新增日志工厂处理原生日志

This commit is contained in:
AL76
2025-03-15 14:52:31 +08:00
parent b33a535b86
commit e6ef2e55e3

View File

@@ -4,7 +4,15 @@ import sys
from types import ModuleType from types import ModuleType
from pathlib import Path from pathlib import Path
# logger.remove() # 保存原生处理器ID
default_handler_id = None
for handler_id in logger._core.handlers:
default_handler_id = handler_id
break
# 移除默认处理器
if default_handler_id is not None:
logger.remove(default_handler_id)
# 类型别名 # 类型别名
LoguruLogger = logger.__class__ LoguruLogger = logger.__class__
@@ -18,31 +26,54 @@ LOG_ROOT = "logs"
# 默认全局配置 # 默认全局配置
DEFAULT_CONFIG = { DEFAULT_CONFIG = {
# 日志级别配置 # 日志级别配置
"console_level": "DEBUG", # 控制台默认级别(可覆盖) "console_level": "DEBUG",
"file_level": "DEBUG", # 文件默认级别(可覆盖) "file_level": "DEBUG",
# 格式配置 # 格式配置
"console_format": ( "console_format": (
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> | " "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
"<level>{level: <8}</level> | " "<level>{level: <8}</level> | "
"<cyan>{extra[module]: <4}</cyan> | " "<cyan>{extra[module]: <12}</cyan> | "
"<level>{message}</level>" "<level>{message}</level>"
), ),
"file_format": ( "file_format": (
"{time:YYYY-MM-DD HH:mm:ss} | " "{time:YYYY-MM-DD HH:mm:ss} | "
"{level: <8} | " "{level: <8} | "
"{extra[module]: <20} | " "{extra[module]: <15} | "
"{message}" "{message}"
), ),
"log_dir": LOG_ROOT, # 默认日志目录,需保留 "log_dir": LOG_ROOT,
"rotation": "100 MB", # 设定轮转 "rotation": "00:00",
"retention": "7 days", # 设定时长 "retention": "3 days",
"compression": "zip", # 设定压缩 "compression": "zip",
} }
def is_registered_module(record: dict) -> bool:
"""检查是否为已注册的模块"""
return record["extra"].get("module") in _handler_registry
def is_unregistered_module(record: dict) -> bool:
"""检查是否为未注册的模块"""
return not is_registered_module(record)
def log_patcher(record: dict) -> None:
"""自动填充未设置模块名的日志记录,保留原生模块名称"""
if "module" not in record["extra"]:
# 尝试从name中提取模块名
module_name = record.get("name", "")
if module_name == "":
module_name = "root"
record["extra"]["module"] = module_name
# 应用全局修补器
logger.configure(patcher=log_patcher)
class LogConfig: class LogConfig:
"""日志配置类""" """日志配置类"""
@@ -68,7 +99,7 @@ def get_module_logger(
module_name = module if isinstance(module, str) else module.__name__ module_name = module if isinstance(module, str) else module.__name__
current_config = config.config if config else DEFAULT_CONFIG current_config = config.config if config else DEFAULT_CONFIG
# 若模块已注册,先移除旧处理器(避免重复添加) # 清理旧处理器
if module_name in _handler_registry: if module_name in _handler_registry:
for handler_id in _handler_registry[module_name]: for handler_id in _handler_registry[module_name]:
logger.remove(handler_id) logger.remove(handler_id)
@@ -82,16 +113,15 @@ def get_module_logger(
level=console_level or current_config["console_level"], level=console_level or current_config["console_level"],
format=current_config["console_format"], format=current_config["console_format"],
filter=lambda record: record["extra"].get("module") == module_name, filter=lambda record: record["extra"].get("module") == module_name,
enqueue=current_config.get("enqueue", True), enqueue=True,
backtrace=current_config.get("backtrace", False),
diagnose=current_config.get("diagnose", False),
) )
handler_ids.append(console_id) handler_ids.append(console_id)
# 文件处理器 # 文件处理器
log_dir = Path(current_config["log_dir"]) log_dir = Path(current_config["log_dir"])
log_dir.mkdir(parents=True, exist_ok=True) log_dir.mkdir(parents=True, exist_ok=True)
log_file = log_dir / f"{module_name}_{{time:YYYY-MM-DD}}.log" log_file = log_dir / module_name / f"{{time:YYYY-MM-DD}}.log"
log_file.parent.mkdir(parents=True, exist_ok=True)
file_id = logger.add( file_id = logger.add(
sink=str(log_file), sink=str(log_file),
@@ -100,9 +130,9 @@ def get_module_logger(
rotation=current_config["rotation"], rotation=current_config["rotation"],
retention=current_config["retention"], retention=current_config["retention"],
compression=current_config["compression"], compression=current_config["compression"],
encoding=current_config.get("encoding", "utf-8"), encoding="utf-8",
filter=lambda record: record["extra"].get("module") == module_name, filter=lambda record: record["extra"].get("module") == module_name,
enqueue=current_config.get("enqueue", True), enqueue=True,
) )
handler_ids.append(file_id) handler_ids.append(file_id)
@@ -124,3 +154,41 @@ def remove_module_logger(module_name: str) -> None:
for handler_id in _handler_registry[module_name]: for handler_id in _handler_registry[module_name]:
logger.remove(handler_id) logger.remove(handler_id)
del _handler_registry[module_name] del _handler_registry[module_name]
# 添加全局默认处理器(只处理未注册模块的日志--->控制台)
DEFAULT_GLOBAL_HANDLER = logger.add(
sink=sys.stderr,
level="DEBUG",
format=(
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
"<level>{level: <8}</level> | "
"<cyan>{name: <12}</cyan> | "
"<level>{message}</level>"
),
filter=is_unregistered_module, # 只处理未注册模块的日志
enqueue=True,
)
# 添加全局默认文件处理器(只处理未注册模块的日志--->logs文件夹
log_dir = Path(DEFAULT_CONFIG["log_dir"])
log_dir.mkdir(parents=True, exist_ok=True)
other_log_dir = log_dir / "other"
other_log_dir.mkdir(parents=True, exist_ok=True)
DEFAULT_FILE_HANDLER = logger.add(
sink=str(other_log_dir / f"{{time:YYYY-MM-DD}}.log"),
level="DEBUG",
format=(
"{time:YYYY-MM-DD HH:mm:ss} | "
"{level: <8} | "
"{name: <15} | "
"{message}"
),
rotation=DEFAULT_CONFIG["rotation"],
retention=DEFAULT_CONFIG["retention"],
compression=DEFAULT_CONFIG["compression"],
encoding="utf-8",
filter=is_unregistered_module, # 只处理未注册模块的日志
enqueue=True,
)