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
 |