119 lines
3.0 KiB
Python
119 lines
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
日志管理模块
|
||
统一管理日志配置和输出
|
||
"""
|
||
|
||
import os
|
||
import logging
|
||
import sys
|
||
from datetime import datetime
|
||
from typing import Optional
|
||
|
||
# 日志目录
|
||
LOG_DIR = os.path.join(os.path.dirname(__file__), "logs")
|
||
|
||
|
||
def setup_logger(
|
||
name: str = "tag_derive",
|
||
level: str = "INFO",
|
||
log_file: Optional[str] = None,
|
||
console: bool = True
|
||
) -> logging.Logger:
|
||
"""
|
||
设置并返回logger
|
||
|
||
Args:
|
||
name: logger名称
|
||
level: 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
||
log_file: 日志文件路径,None则不写入文件
|
||
console: 是否输出到控制台
|
||
"""
|
||
logger = logging.getLogger(name)
|
||
|
||
# 避免重复添加handler
|
||
if logger.handlers:
|
||
return logger
|
||
|
||
logger.setLevel(getattr(logging, level.upper(), logging.INFO))
|
||
|
||
# 日志格式
|
||
formatter = logging.Formatter(
|
||
fmt="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
||
datefmt="%Y-%m-%d %H:%M:%S"
|
||
)
|
||
|
||
# 控制台输出
|
||
if console:
|
||
console_handler = logging.StreamHandler(sys.stdout)
|
||
console_handler.setFormatter(formatter)
|
||
logger.addHandler(console_handler)
|
||
|
||
# 文件输出
|
||
if log_file:
|
||
# 确保日志目录存在
|
||
os.makedirs(os.path.dirname(log_file), exist_ok=True)
|
||
file_handler = logging.FileHandler(log_file, encoding="utf-8")
|
||
file_handler.setFormatter(formatter)
|
||
logger.addHandler(file_handler)
|
||
|
||
return logger
|
||
|
||
|
||
def get_default_log_file() -> str:
|
||
"""获取默认日志文件路径(按日期)"""
|
||
os.makedirs(LOG_DIR, exist_ok=True)
|
||
date_str = datetime.now().strftime("%Y%m%d")
|
||
return os.path.join(LOG_DIR, f"tag_derive_{date_str}.log")
|
||
|
||
|
||
# 默认logger实例
|
||
_default_logger = None
|
||
|
||
|
||
def get_logger(name: str = "tag_derive") -> logging.Logger:
|
||
"""获取logger实例"""
|
||
global _default_logger
|
||
if _default_logger is None:
|
||
_default_logger = setup_logger(
|
||
name=name,
|
||
level="INFO",
|
||
log_file=get_default_log_file(),
|
||
console=True
|
||
)
|
||
return _default_logger
|
||
|
||
|
||
class LogMixin:
|
||
"""日志混入类,为类提供日志能力"""
|
||
|
||
@property
|
||
def logger(self) -> logging.Logger:
|
||
if not hasattr(self, '_logger'):
|
||
self._logger = get_logger(self.__class__.__name__)
|
||
return self._logger
|
||
|
||
|
||
# ============== 便捷函数 ==============
|
||
def log_info(msg: str, *args):
|
||
get_logger().info(msg, *args)
|
||
|
||
def log_error(msg: str, *args):
|
||
get_logger().error(msg, *args)
|
||
|
||
def log_warning(msg: str, *args):
|
||
get_logger().warning(msg, *args)
|
||
|
||
def log_debug(msg: str, *args):
|
||
get_logger().debug(msg, *args)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# 测试日志
|
||
logger = get_logger()
|
||
logger.info("日志系统初始化成功")
|
||
logger.debug("这是DEBUG日志")
|
||
logger.warning("这是WARNING日志")
|
||
logger.error("这是ERROR日志")
|
||
print(f"日志文件: {get_default_log_file()}")
|