Repository navigation
Expand file tree
/
Copy pathlogger.py
More file actions
164 lines (137 loc) · 5.53 KB
/
Copy pathlogger.py
File metadata and controls
164 lines (137 loc) · 5.53 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import logging
import logging.config
import sys
from logging.handlers import RotatingFileHandler
from pathlib import Path
from typing import Any
from paths import LOG_DIR, LOG_FILE_PATH
# 尝试导入 colorlog 库
if hasattr(sys.stdout, "isatty") and sys.stdout.isatty():
try:
import colorlog # noqa: F401
enable_color = True
except Exception:
enable_color = False
else:
enable_color = False
class UIautomationFilter(logging.Filter):
"""
过滤 comtypes 的低于 WARNING 等级的日志。
"""
def filter(self, record: logging.LogRecord) -> bool | logging.LogRecord:
if "comtypes" in record.name:
return record.levelno >= logging.WARNING
return True
# 默认日志配置字典
# 格式化日志输出到文件和终端, 日志等级为 debug
# 过滤器 UIautomationFilter
DEFAULT_LOGGING_CONFIG: dict[str, Any] = {
"version": 1,
"disable_existing_loggers": False, # 保持为 False 以避免清除掉其他软件包添加的 logger
"filters": {"silence_uiautomation_less_than_info": {"()": f"{__name__}.UIautomationFilter"}},
"formatters": {
"default": {
"format": "[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
"color": {
"()": "colorlog.ColoredFormatter",
"format": "%(log_color)s[%(asctime)s] [%(levelname)s] [%(name)s]%(reset)s %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
"log_colors": {
"DEBUG": "white",
"INFO": "cyan",
"WARNING": "yellow",
"ERROR": "red",
"CRITICAL": "bold_red",
},
},
"file_formatter": {
"format": "[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "color" if enable_color else "default",
"level": "DEBUG",
"filters": ["silence_uiautomation_less_than_info"],
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"formatter": "file_formatter",
"filename": str(LOG_FILE_PATH),
"maxBytes": 10485760, # 10MB
"backupCount": 5,
"encoding": "utf8",
"level": "DEBUG",
"filters": ["silence_uiautomation_less_than_info"],
},
},
"root": {
"handlers": ["console", "file"],
"level": "DEBUG", # 根 logger 的级别建议设为 DEBUG
},
}
if "handlers" in DEFAULT_LOGGING_CONFIG and "file" in DEFAULT_LOGGING_CONFIG["handlers"]:
# 如果启用了文件日志,则确保日志文件夹已创建
log_filename: Path | None = Path(DEFAULT_LOGGING_CONFIG["handlers"]["file"]["filename"])
LOG_DIR.mkdir(parents=True, exist_ok=True)
else:
log_filename = None
# 应用日志设置
logging.config.dictConfig(DEFAULT_LOGGING_CONFIG)
if log_filename:
logging.getLogger(__name__).info(f"程序日志将被记录到文件: {log_filename}")
def set_loglevel(log_level: str):
"""
设置控制台日志等级。
:param log_level: 日志等级: 'DEBUG','INFO','WARNING','ERROR','CRITICAL'
"""
# 输入验证
if log_level.upper() not in ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"):
raise ValueError(
f"输入的日志等级无效: {log_level} 。日志等级应当为'DEBUG','INFO','WARNING','ERROR','CRITICAL'中的一个"
)
# 应用设置
for handler in logging.getLogger().handlers:
if handler.name == "console":
handler.setLevel(log_level.upper())
return
logging.getLogger(__name__).warning("未找到控制台日志处理器,因此没有应用控制台日志等级设置。")
def get_logger(name: str) -> logging.Logger:
"""
获取一个 logger 实例。
:param name: logger 的名称
:return: logging.Logger
"""
return logging.getLogger(name)
# --- 使用示例 ---
if __name__ == "__main__":
# 传入不同的 name 来演示模块名的显示效果
main_logger = get_logger(name="main")
ocr_logger = get_logger(name="ocr_engine")
window_logger = get_logger(name="window_utils")
print("\n--- 诊断信息 ---")
root_logger = logging.getLogger()
print(f"Root logger 的有效级别是: {logging.getLevelName(root_logger.getEffectiveLevel())}")
# 检查文件处理器的级别
for handler in root_logger.handlers:
if isinstance(handler, RotatingFileHandler):
print(f"文件处理器 ({handler.baseFilename}) 的级别是: {logging.getLevelName(handler.level)}")
print("--- 诊断结束 ---\n")
print("\n--- 日志功能演示 ---")
# 现在 logger 的输出会包含模块名和对齐的级别
main_logger.debug("这是一条来自 main 模块的调试信息。")
ocr_logger.info("正在初始化 OCR 引擎...")
main_logger.warning("主程序检测到一个潜在问题。")
window_logger.error("未找到 GTA V 窗口。请先启动游戏。")
player_name = "Player123"
score = 500
main_logger.info(f"玩家 '{player_name}' 成功完成任务,得分: {score}")
main_logger.critical("发生严重错误,程序即将退出!")
print("\n--- 日志演示结束 ---")
if not enable_color:
print("\n提示: 'colorlog' 库未安装,日志将不带颜色。")
print("请在命令行运行 'pip install colorlog' 来启用彩色日志。")