auto_build_launcher/utils/logger_utils.py

155 lines
4.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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