119 lines
3.4 KiB
Python
119 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
统一日志配置模块
|
|
提供标准化的日志配置
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import logging
|
|
import logging.handlers
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
|
|
# 日志格式
|
|
CONSOLE_FORMAT = "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s"
|
|
FILE_FORMAT = "%(asctime)s | %(levelname)-8s | %(name)s | %(filename)s:%(lineno)d | %(message)s"
|
|
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
|
|
|
|
|
def setup_logging(
|
|
level: str = "INFO",
|
|
log_dir: Optional[str] = None,
|
|
log_file: str = "app.log",
|
|
max_bytes: int = 10 * 1024 * 1024, # 10MB
|
|
backup_count: int = 5,
|
|
console: bool = True,
|
|
file: bool = True
|
|
) -> None:
|
|
"""
|
|
配置全局日志
|
|
|
|
Args:
|
|
level: 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
log_dir: 日志目录 (默认: logs/)
|
|
log_file: 日志文件名
|
|
max_bytes: 单个日志文件最大大小
|
|
backup_count: 保留的日志文件数量
|
|
console: 是否输出到控制台
|
|
file: 是否输出到文件
|
|
"""
|
|
# 确定日志目录
|
|
if log_dir is None:
|
|
log_dir = os.environ.get("LOG_DIR", "logs")
|
|
|
|
log_path = Path(log_dir)
|
|
log_path.mkdir(parents=True, exist_ok=True)
|
|
|
|
# 获取根日志器
|
|
root_logger = logging.getLogger()
|
|
root_logger.setLevel(getattr(logging, level.upper(), logging.INFO))
|
|
|
|
# 清除现有处理器
|
|
root_logger.handlers.clear()
|
|
|
|
# 控制台处理器
|
|
if console:
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(logging.DEBUG)
|
|
console_handler.setFormatter(logging.Formatter(CONSOLE_FORMAT, DATE_FORMAT))
|
|
root_logger.addHandler(console_handler)
|
|
|
|
# 文件处理器 (滚动)
|
|
if file:
|
|
file_handler = logging.handlers.RotatingFileHandler(
|
|
log_path / log_file,
|
|
maxBytes=max_bytes,
|
|
backupCount=backup_count,
|
|
encoding='utf-8'
|
|
)
|
|
file_handler.setLevel(logging.DEBUG)
|
|
file_handler.setFormatter(logging.Formatter(FILE_FORMAT, DATE_FORMAT))
|
|
root_logger.addHandler(file_handler)
|
|
|
|
# 错误日志单独文件
|
|
error_handler = logging.handlers.RotatingFileHandler(
|
|
log_path / "error.log",
|
|
maxBytes=max_bytes,
|
|
backupCount=backup_count,
|
|
encoding='utf-8'
|
|
)
|
|
error_handler.setLevel(logging.ERROR)
|
|
error_handler.setFormatter(logging.Formatter(FILE_FORMAT, DATE_FORMAT))
|
|
root_logger.addHandler(error_handler)
|
|
|
|
# 设置第三方库日志级别
|
|
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
|
logging.getLogger("httpx").setLevel(logging.WARNING)
|
|
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
|
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
|
|
|
logging.info(f"日志配置完成: level={level}, dir={log_dir}")
|
|
|
|
|
|
def get_logger(name: str) -> logging.Logger:
|
|
"""
|
|
获取命名日志器
|
|
|
|
Args:
|
|
name: 日志器名称
|
|
|
|
Returns:
|
|
Logger 实例
|
|
"""
|
|
return logging.getLogger(name)
|
|
|
|
|
|
# 便捷函数
|
|
def init_logging_from_env():
|
|
"""从环境变量初始化日志配置"""
|
|
setup_logging(
|
|
level=os.environ.get("LOG_LEVEL", "INFO"),
|
|
log_dir=os.environ.get("LOG_DIR", "logs"),
|
|
console=os.environ.get("LOG_CONSOLE", "true").lower() == "true",
|
|
file=os.environ.get("LOG_FILE", "true").lower() == "true"
|
|
)
|