|
|
|
|
|
|
|
|
"""
|
|
|
统一的日志系统配置
|
|
|
"""
|
|
|
import logging
|
|
|
from logging.handlers import RotatingFileHandler
|
|
|
from pathlib import Path
|
|
|
from typing import Optional
|
|
|
|
|
|
class LoggerFactory:
|
|
|
"""日志工厂类,用于创建统一配置的logger"""
|
|
|
|
|
|
DEFAULT_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
|
|
|
|
|
@classmethod
|
|
|
def create_logger(
|
|
|
cls,
|
|
|
name: str,
|
|
|
log_file: str,
|
|
|
log_dir: Path = Path("logs"),
|
|
|
max_bytes: int = 10*1024*1024,
|
|
|
backup_count: int = 5,
|
|
|
console_level: int = logging.WARNING,
|
|
|
file_level: int = logging.INFO
|
|
|
) -> logging.Logger:
|
|
|
"""
|
|
|
创建一个配置好的logger实例
|
|
|
|
|
|
Args:
|
|
|
name: Logger名称
|
|
|
log_file: 日志文件名
|
|
|
log_dir: 日志目录
|
|
|
max_bytes: 单个日志文件最大大小
|
|
|
backup_count: 日志文件备份数量
|
|
|
console_level: 控制台输出级别
|
|
|
file_level: 文件输出级别
|
|
|
"""
|
|
|
|
|
|
logger = logging.getLogger(name)
|
|
|
logger.setLevel(min(console_level, file_level))
|
|
|
|
|
|
|
|
|
for handler in logger.handlers[:]:
|
|
|
logger.removeHandler(handler)
|
|
|
|
|
|
|
|
|
file_handler_added = False
|
|
|
try:
|
|
|
|
|
|
log_dir.mkdir(exist_ok=True)
|
|
|
|
|
|
|
|
|
file_handler = RotatingFileHandler(
|
|
|
log_dir / log_file,
|
|
|
maxBytes=max_bytes,
|
|
|
backupCount=backup_count,
|
|
|
encoding='utf-8'
|
|
|
)
|
|
|
file_handler.setLevel(file_level)
|
|
|
|
|
|
|
|
|
formatter = logging.Formatter(cls.DEFAULT_FORMAT)
|
|
|
file_handler.setFormatter(formatter)
|
|
|
|
|
|
|
|
|
logger.addHandler(file_handler)
|
|
|
file_handler_added = True
|
|
|
except (PermissionError, OSError) as e:
|
|
|
|
|
|
print(f"Warning: Unable to create log file '{log_file}': {e}", file=__import__('sys').stderr)
|
|
|
print(f"Logging will only output to console.", file=__import__('sys').stderr)
|
|
|
|
|
|
|
|
|
console_handler = logging.StreamHandler()
|
|
|
|
|
|
if not file_handler_added:
|
|
|
console_handler.setLevel(logging.INFO)
|
|
|
else:
|
|
|
console_handler.setLevel(console_level)
|
|
|
|
|
|
|
|
|
formatter = logging.Formatter(cls.DEFAULT_FORMAT)
|
|
|
console_handler.setFormatter(formatter)
|
|
|
|
|
|
|
|
|
logger.addHandler(console_handler)
|
|
|
|
|
|
return logger
|
|
|
|
|
|
|
|
|
def get_logger(name: str = "default") -> logging.Logger:
|
|
|
"""获取logger实例,使用统一的配置"""
|
|
|
return LoggerFactory.create_logger(
|
|
|
name=name,
|
|
|
log_file=f"{name}.log"
|
|
|
) |