huoyan-enterprise/backend/logger/logging.py

167 lines
5.0 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.

"""
日志配置模块
使用 Loguru 作为日志框架,提供统一的日志配置和管理。
支持日志文件轮转按大小30MB和日期切割。
Loguru 的优势:
- 简单易用,无需复杂配置
- 自动格式化,支持彩色输出
- 内置日志轮转功能
- 性能优秀
- 支持结构化日志
"""
import sys
from pathlib import Path
from typing import Optional
from loguru import logger
def setup_logger(
log_level: Optional[str] = None,
log_dir: Optional[Path] = None,
max_file_size: Optional[str] = None,
retention_days: Optional[int] = None,
enable_console: Optional[bool] = None,
) -> None:
"""
配置和初始化 Loguru 日志系统
这个函数会:
1. 移除默认的日志处理器
2. 添加控制台输出(可选)
3. 添加文件输出,支持自动轮转
Args:
log_level: 日志级别DEBUG, INFO, WARNING, ERROR, CRITICAL
如果为 None则从配置文件读取
log_dir: 日志文件存储目录,默认为项目根目录下的 logs 文件夹
max_file_size: 单个日志文件的最大大小,达到后会自动切割
支持格式30 MB, 100 KB, 1 GB 等
retention_days: 日志文件保留天数,超过此天数的日志文件会被自动删除
enable_console: 是否启用控制台输出
Example:
>>> setup_logger()
>>> logger.info("这是一条日志")
"""
# 延迟导入配置,避免循环依赖
from core.config import settings
# 从配置读取日志级别,如果没有指定
if log_level is None:
log_level = settings.logging_level.upper()
# 从配置读取文件大小限制
if max_file_size is None:
max_file_size = settings.logging_max_file_size
# 从配置读取保留天数
if retention_days is None:
retention_days = settings.logging_retention_days
# 从配置读取是否启用控制台输出
if enable_console is None:
enable_console = settings.logging_enable_console
# 确定日志目录
if log_dir is None:
# 从配置读取日志目录,默认为项目根目录下的 logs 文件夹
log_dir_name = settings.logging_dir
# 如果是绝对路径,直接使用
if Path(log_dir_name).is_absolute():
log_dir = Path(log_dir_name)
else:
# 相对路径:使用项目根目录
# __file__ 是 backend/logger/logging.py需要向上两级到项目根目录
project_root = Path(__file__).parent.parent
log_dir = project_root / log_dir_name
else:
log_dir = Path(log_dir)
# 确保日志目录存在
# 如果 log_dir 是一个文件,先删除它
if log_dir.exists() and log_dir.is_file():
logger.warning(f"日志路径 {log_dir} 是一个文件,将其重命名为 {log_dir}_backup")
log_dir.rename(log_dir.parent / f"{log_dir.name}_backup")
log_dir.mkdir(parents=True, exist_ok=True)
# 移除 Loguru 的默认处理器
# Loguru 默认会输出到 stderr我们需要移除它以便自定义配置
logger.remove()
# 配置日志格式
log_format = (
"<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
"<level>{level: <8}</level> | "
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | "
"<level>{message}</level>"
)
# 添加控制台输出(可选)
if enable_console:
logger.add(
sys.stderr,
format=log_format,
level=log_level,
colorize=True,
backtrace=True,
diagnose=True,
)
# 添加文件输出 - 所有级别的日志
logger.add(
log_dir / "huoyan_{time:YYYY-MM-DD}.log",
format=log_format,
level=log_level,
rotation="00:00",
retention=f"{retention_days} days",
compression="zip",
encoding="utf-8",
backtrace=True,
diagnose=True,
enqueue=True,
)
# 单独记录错误日志
logger.add(
log_dir / "huoyan_error_{time:YYYY-MM-DD}.log",
format=log_format,
level="ERROR",
rotation="00:00",
retention=f"{retention_days} days",
compression="zip",
encoding="utf-8",
backtrace=True,
diagnose=True,
enqueue=True,
)
# 记录配置信息
logger.info(f"日志系统已初始化")
logger.info(f"日志级别: {log_level}")
logger.info(f"日志目录: {log_dir}")
logger.info(f"文件大小限制: {max_file_size}")
logger.info(f"日志保留天数: {retention_days}")
def get_logger(name: Optional[str] = None):
"""
获取日志记录器实例
Args:
name: 日志记录器的名称,通常是 __name__模块名
Returns:
Loguru 日志记录器实例
"""
if name:
return logger.bind(name=name)
return logger
__all__ = ["logger", "setup_logger", "get_logger"]