155 lines
4.8 KiB
Python
155 lines
4.8 KiB
Python
|
import logging
|
|||
|
import os
|
|||
|
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
|
|||
|
from typing import Union
|
|||
|
|
|||
|
|
|||
|
class Logger:
|
|||
|
"""
|
|||
|
日志工具类封装
|
|||
|
|
|||
|
功能:
|
|||
|
1. 支持控制台和文件两种输出方式
|
|||
|
2. 支持按大小或时间轮转日志文件
|
|||
|
3. 支持自定义日志格式
|
|||
|
4. 支持不同日志级别
|
|||
|
5. 线程安全
|
|||
|
"""
|
|||
|
|
|||
|
def __init__(
|
|||
|
self,
|
|||
|
name: str = "root",
|
|||
|
level: Union[int, str] = logging.INFO,
|
|||
|
console: bool = True,
|
|||
|
file: bool = False,
|
|||
|
file_path: str = "logs/app.log",
|
|||
|
max_bytes: int = 10 * 1024 * 1024, # 10MB
|
|||
|
backup_count: int = 5,
|
|||
|
when: str = "midnight",
|
|||
|
interval: int = 1,
|
|||
|
fmt: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|||
|
datefmt: str = "%Y-%m-%d %H:%M:%S",
|
|||
|
mode: str = "size" # 'size' 或 'time'
|
|||
|
):
|
|||
|
"""
|
|||
|
初始化日志工具
|
|||
|
|
|||
|
:param name: 日志名称
|
|||
|
:param level: 日志级别
|
|||
|
:param console: 是否输出到控制台
|
|||
|
:param file: 是否输出到文件
|
|||
|
:param file_path: 日志文件路径
|
|||
|
:param max_bytes: 每个日志文件的最大大小(字节),仅mode='size'时有效
|
|||
|
:param backup_count: 保留的备份日志文件数量
|
|||
|
:param when: 日志轮转时间单位,如'S'(秒)、'M'(分)、'H'(小时)、'D'(天)、'midnight'(午夜),仅mode='time'时有效
|
|||
|
:param interval: 轮转间隔,仅mode='time'时有效
|
|||
|
:param fmt: 日志格式
|
|||
|
:param datefmt: 日期格式
|
|||
|
:param mode: 日志轮转模式,'size'按大小轮转,'time'按时间轮转
|
|||
|
"""
|
|||
|
self.logger = logging.getLogger(name)
|
|||
|
self.logger.setLevel(level)
|
|||
|
|
|||
|
# 避免重复添加handler
|
|||
|
if self.logger.handlers:
|
|||
|
return
|
|||
|
|
|||
|
formatter = logging.Formatter(fmt=fmt, datefmt=datefmt)
|
|||
|
|
|||
|
# 控制台输出
|
|||
|
if console:
|
|||
|
console_handler = logging.StreamHandler()
|
|||
|
console_handler.setFormatter(formatter)
|
|||
|
self.logger.addHandler(console_handler)
|
|||
|
|
|||
|
# 文件输出
|
|||
|
if file:
|
|||
|
# 创建日志目录
|
|||
|
log_dir = os.path.dirname(file_path)
|
|||
|
if log_dir and not os.path.exists(log_dir):
|
|||
|
os.makedirs(log_dir)
|
|||
|
|
|||
|
if mode == "size":
|
|||
|
# 按大小轮转
|
|||
|
file_handler = RotatingFileHandler(
|
|||
|
filename=file_path,
|
|||
|
maxBytes=max_bytes,
|
|||
|
backupCount=backup_count,
|
|||
|
encoding="utf-8"
|
|||
|
)
|
|||
|
else:
|
|||
|
# 按时间轮转
|
|||
|
file_handler = TimedRotatingFileHandler(
|
|||
|
filename=file_path,
|
|||
|
when=when,
|
|||
|
interval=interval,
|
|||
|
backupCount=backup_count,
|
|||
|
encoding="utf-8"
|
|||
|
)
|
|||
|
|
|||
|
file_handler.setFormatter(formatter)
|
|||
|
self.logger.addHandler(file_handler)
|
|||
|
|
|||
|
def debug(self, msg: str, *args, **kwargs):
|
|||
|
"""记录调试信息"""
|
|||
|
self.logger.debug(msg, *args, **kwargs)
|
|||
|
|
|||
|
def info(self, msg: str, *args, **kwargs):
|
|||
|
"""记录普通信息"""
|
|||
|
self.logger.info(msg, *args, **kwargs)
|
|||
|
|
|||
|
def warning(self, msg: str, *args, **kwargs):
|
|||
|
"""记录警告信息"""
|
|||
|
self.logger.warning(msg, *args, **kwargs)
|
|||
|
|
|||
|
def error(self, msg: str, *args, **kwargs):
|
|||
|
"""记录错误信息"""
|
|||
|
self.logger.error(msg, *args, **kwargs)
|
|||
|
|
|||
|
def critical(self, msg: str, *args, **kwargs):
|
|||
|
"""记录严重错误信息"""
|
|||
|
self.logger.critical(msg, *args, **kwargs)
|
|||
|
|
|||
|
def exception(self, msg: str, *args, exc_info=True, **kwargs):
|
|||
|
"""记录异常信息"""
|
|||
|
self.logger.exception(msg, *args, exc_info=exc_info, **kwargs)
|
|||
|
|
|||
|
def log(self, level: int, msg: str, *args, **kwargs):
|
|||
|
"""通用日志记录方法"""
|
|||
|
self.logger.log(level, msg, *args, **kwargs)
|
|||
|
|
|||
|
def set_level(self, level: Union[int, str]):
|
|||
|
"""设置日志级别"""
|
|||
|
self.logger.setLevel(level)
|
|||
|
|
|||
|
def add_handler(self, handler: logging.Handler):
|
|||
|
"""添加自定义handler"""
|
|||
|
self.logger.addHandler(handler)
|
|||
|
|
|||
|
def remove_handler(self, handler: logging.Handler):
|
|||
|
"""移除handler"""
|
|||
|
self.logger.removeHandler(handler)
|
|||
|
|
|||
|
|
|||
|
logger: Logger
|
|||
|
|
|||
|
|
|||
|
def app_logger() -> Logger:
|
|||
|
return logger
|
|||
|
|
|||
|
|
|||
|
def init() -> Logger:
|
|||
|
# 创建日志实例
|
|||
|
global logger
|
|||
|
logger = Logger(
|
|||
|
name="my_app",
|
|||
|
level=logging.DEBUG,
|
|||
|
console=True,
|
|||
|
file=True,
|
|||
|
file_path="logs/app.log",
|
|||
|
max_bytes=1024 * 1024, # 1MB
|
|||
|
backup_count=3,
|
|||
|
mode="size"
|
|||
|
)
|
|||
|
return logger
|