File size: 3,418 Bytes
47258ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from pathlib import Path
from loguru import logger

# Global logger instance
app_logger = None


def setup_logger(log_dir, log_retention_days=7, log_rotation="1 day", debug_mode=False):
    """
    Create a logger instance

    Parameters:
        log_dir (str): 日志目录
        log_retention_days (int): 日志保留天数
        log_rotation (str): 日志轮转间隔
        debug_mode (bool): 是否开启调试模式
    """
    global app_logger

    # 移除所有现有的日志处理器(支持热重载)
    logger.remove()

    log_level = "DEBUG" if debug_mode else "INFO"

    console_format = (
        "<green>{time:HH:mm:ss}</green> | <level>{level: <8}</level> | <level>{message}</level>"
        if not debug_mode
        else "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | "
        "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | <level>{message}</level>"
    )

    # 添加控制台输出(根据 debug_mode 设置级别)
    logger.add(sys.stderr, level=log_level, format=console_format, colorize=True)

    # 只有在 debug_mode 时才添加文件输出
    if debug_mode:
        try:
            log_path = Path(log_dir)
            log_path.mkdir(parents=True, exist_ok=True)

            log_file = log_path / "{time:YYYY-MM-DD}.log"
            file_format = "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} | {message}"

            logger.add(
                str(log_file),
                level=log_level,
                format=file_format,
                rotation=log_rotation,
                retention=f"{log_retention_days} days",
                encoding="utf-8",
                compression="zip",
                enqueue=True,
                catch=True,
            )
        except (PermissionError, OSError) as e:
            # 如果无法创建日志目录或文件,降级为仅控制台输出
            logger.warning(f"⚠️ 无法创建日志文件 ({e}),将仅使用控制台输出")

    app_logger = logger

    return logger


def get_logger():
    """Get the logger instance"""
    global app_logger
    if app_logger is None:
        # 如果没有设置过logger,使用默认配置
        logger.remove()  # 移除所有现有处理器
        logger.add(sys.stderr, level="INFO", 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>")
        app_logger = logger
    return app_logger


if __name__ == "__main__":
    """Test the logger"""
    import tempfile

    with tempfile.TemporaryDirectory() as temp_dir:
        try:
            setup_logger(temp_dir, debug_mode=True)

            logger.debug("这是一条调试日志")
            logger.info("这是一条信息日志")
            logger.warning("这是一条警告日志")
            logger.error("这是一条错误日志")
            logger.critical("这是一条严重日志")

            try:
                1 / 0
            except ZeroDivisionError:
                logger.exception("发生了除零异常")

            print("✅ 日志测试完成")

            logger.remove()

        except Exception as e:
            print(f"❌ 日志测试失败: {e}")
            logger.remove()
            raise