|
|
@@ -1,13 +1,14 @@
|
|
|
# logger_config.py
|
|
|
|
|
|
import logging
|
|
|
-from logging.handlers import RotatingFileHandler
|
|
|
+# from logging.handlers import RotatingFileHandler <-- 注释掉原来的
|
|
|
+from concurrent_log_handler import ConcurrentRotatingFileHandler # <-- 导入新的处理程序
|
|
|
import sys
|
|
|
import os
|
|
|
|
|
|
# 定义日志文件的路径
|
|
|
-LOG_DIR = 'logs' # 日志文件夹名称
|
|
|
-LOG_FILE = os.path.join(LOG_DIR, 'app.log') # 日志文件名
|
|
|
+LOG_DIR = 'logs'
|
|
|
+LOG_FILE = os.path.join(LOG_DIR, 'app.log')
|
|
|
|
|
|
IS_LOGGOER_CONFIG = False
|
|
|
|
|
|
@@ -19,33 +20,30 @@ def setup_logging(log_level=logging.INFO):
|
|
|
"""
|
|
|
配置项目的日志记录。
|
|
|
"""
|
|
|
- # 获取根日志记录器
|
|
|
root_logger = logging.getLogger()
|
|
|
- root_logger.setLevel(log_level) # 设置根日志记录器的最低级别
|
|
|
+ root_logger.setLevel(log_level)
|
|
|
|
|
|
# 避免重复添加处理程序
|
|
|
if not root_logger.handlers:
|
|
|
- # 创建文件处理程序 (使用 RotatingFileHandler 实现日志文件旋转)
|
|
|
- file_handler = RotatingFileHandler(
|
|
|
+ # 创建文件处理程序 (使用 ConcurrentRotatingFileHandler)
|
|
|
+ # 它会在进程间同步,安全地进行日志轮转
|
|
|
+ file_handler = ConcurrentRotatingFileHandler(
|
|
|
LOG_FILE,
|
|
|
- maxBytes=1024 * 1024 * 5, # 最大 5MB
|
|
|
- backupCount=5, # 保留 5 个备份文件
|
|
|
- encoding='utf-8' # 指定编码为 UTF-8,解决中文乱码
|
|
|
+ "a", # 使用追加模式 'a'
|
|
|
+ maxBytes=1024 * 1024 * 5,
|
|
|
+ backupCount=5,
|
|
|
+ encoding='utf-8'
|
|
|
)
|
|
|
- file_handler.setLevel(log_level) # 设置文件处理程序的最低级别
|
|
|
+ file_handler.setLevel(log_level)
|
|
|
|
|
|
- # 创建控制台处理程序
|
|
|
+ # 控制台处理程序保持不变
|
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
|
- console_handler.setLevel(log_level) # 设置控制台处理程序的最低级别
|
|
|
+ console_handler.setLevel(log_level)
|
|
|
|
|
|
- # 创建一个格式化器
|
|
|
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
|
-
|
|
|
- # 将格式化器添加到处理程序
|
|
|
file_handler.setFormatter(formatter)
|
|
|
console_handler.setFormatter(formatter)
|
|
|
|
|
|
- # 将处理程序添加到根日志记录器
|
|
|
root_logger.addHandler(file_handler)
|
|
|
root_logger.addHandler(console_handler)
|
|
|
|
|
|
@@ -55,16 +53,7 @@ def setup_logging(log_level=logging.INFO):
|
|
|
def get_logger(name=None):
|
|
|
"""
|
|
|
获取一个日志记录器实例。
|
|
|
- 如果 name 为 None,返回根日志记录器。
|
|
|
- 否则,返回指定名称的日志记录器。
|
|
|
"""
|
|
|
- # 如果还没有配置日志,先进行配置
|
|
|
if not IS_LOGGOER_CONFIG:
|
|
|
- setup_logging() # 使用默认级别 INFO 进行配置
|
|
|
-
|
|
|
- return logging.getLogger(name)
|
|
|
-
|
|
|
-# 在模块加载时自动进行一次基本配置
|
|
|
-# 这样即使没有显式调用 setup_logging,第一次调用 get_logger 也会触发配置
|
|
|
-# 但更好的做法是在项目的入口点显式调用 setup_logging
|
|
|
-# setup_logging() # 可以在此处调用,但建议在主脚本中调用
|
|
|
+ setup_logging()
|
|
|
+ return logging.getLogger(name)
|