Files
SupervisorAI/utils/logger.py

107 lines
2.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 sys
from typing import Optional
from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler
import os
import platform
from config import settings
def setup_logger(
name: str,
level: Optional[str] = None,
log_file: Optional[str] = None
) -> logging.Logger:
"""
配置和获取logger多进程安全版本
Args:
name: logger名称
level: 日志级别
log_file: 日志文件路径
Returns:
配置好的logger实例
"""
# 获取日志级别
if level is None:
level = settings.LOG_LEVEL
log_level = getattr(logging, level.upper(), logging.INFO)
# 创建logger
logger = logging.getLogger(name)
logger.setLevel(log_level)
# 避免重复添加handler
if logger.handlers:
return logger
# 创建formatter
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# 控制台handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(log_level)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# 文件handler如果配置了日志文件
if log_file or settings.LOG_FILE:
file_path = log_file or settings.LOG_FILE
# 为每个进程生成唯一的日志文件名(避免文件锁定)
process_id = os.getpid()
process_hash = hash(f"{process_id}_{name}") % 10000 # 简单的hash
# 生成唯一的日志文件名
base_name, ext = os.path.splitext(file_path)
unique_file_path = f"{base_name}_{process_hash:04d}{ext}"
try:
# 使用进程安全的文件handler
file_handler = TimedRotatingFileHandler(
unique_file_path,
when='midnight', # 每天午夜轮转
interval=1, # 间隔1天
backupCount=0, # 永久保留
encoding='utf-8'
)
file_handler.setLevel(log_level)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# 记录使用的日志文件路径
logger.info(f"Logger initialized with file: {unique_file_path}")
except Exception as e:
logger.warning(f"Failed to create log file handler: {e}")
# 回退到控制台日志
logger.warning("Falling back to console logging only")
return logger
# 创建根logger
root_logger = setup_logger("sur_face_feature")
def get_logger(name: str) -> logging.Logger:
"""
获取指定名称的logger
Args:
name: logger名称
Returns:
logger实例
"""
return setup_logger(name)