Skip to content

Commit 3aecf71

Browse files
committed
refactor(core): 重构日志记录系统并优化代码格式
- 移除全局 logging 配置,改为使用自定义 logger - 优化代码格式,包括缩进、空格和注释 - 更新导入语句,移除未使用的 import - 改进异常处理和日志记录细节
1 parent e5d25b4 commit 3aecf71

8 files changed

Lines changed: 314 additions & 261 deletions

File tree

main.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
11
import asyncio
2-
import logging
32
import signal
43
import sys
54
import os
6-
import argparse # 导入 argparse
5+
import argparse # 导入 argparse
76

87
# 尝试导入 tomllib (Python 3.11+), 否则使用 toml
98
try:
109
import tomllib
1110
except ModuleNotFoundError:
1211
try:
13-
import toml as tomllib # type: ignore
12+
import toml as tomllib # type: ignore
1413
except ModuleNotFoundError:
1514
print("错误:需要安装 TOML 解析库。请运行 'pip install toml'", file=sys.stderr)
1615
sys.exit(1)
1716

1817
# 从 src 目录导入核心类和插件管理器
1918
from src.core.vup_next_core import VupNextCore
2019
from src.core.plugin_manager import PluginManager
21-
22-
# 配置日志 (移到 main 函数内部,根据参数设置)
23-
logger = logging.getLogger("VUP-NEXT-Main") # 获取 logger 实例可以提前
20+
from src.utils.logger import logger
2421

2522
# 获取 main.py 文件所在的目录
2623
_BASE_DIR = os.path.dirname(os.path.abspath(__file__))
2724

25+
2826
def load_config(config_filename: str = "config.toml") -> dict:
2927
"""加载位于脚本同目录下的 TOML 配置文件。"""
3028
config_path = os.path.join(_BASE_DIR, config_filename)
@@ -44,6 +42,7 @@ def load_config(config_filename: str = "config.toml") -> dict:
4442
logger.error(f"加载配置文件 '{config_path}' 时发生未知错误: {e}", exc_info=True)
4543
sys.exit(1)
4644

45+
4746
async def main():
4847
"""应用程序主入口点。"""
4948

@@ -55,19 +54,18 @@ async def main():
5554
args = parser.parse_args()
5655

5756
# --- 配置日志 ---
58-
log_level = logging.DEBUG if args.debug else logging.INFO
59-
logging.basicConfig(
60-
level=log_level,
61-
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
62-
handlers=[
63-
logging.StreamHandler(sys.stdout) # 默认输出到控制台
64-
]
65-
)
66-
67-
logger.info("启动 VUP-NEXT 应用程序...")
6857
if args.debug:
58+
logger.remove() # 移除之前的handler
59+
logger.add(
60+
sys.stderr,
61+
level="DEBUG",
62+
colorize=True,
63+
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>",
64+
)
6965
logger.info("已启用 DEBUG 日志级别。")
7066

67+
logger.info("启动 VUP-NEXT 应用程序...")
68+
7169
# --- 加载配置 ---
7270
config = load_config()
7371

@@ -92,23 +90,23 @@ async def main():
9290
platform=platform_id,
9391
maicore_host=maicore_host,
9492
maicore_port=maicore_port,
95-
http_host=http_host, # 如果 http_enabled=False, 这里会是 None
93+
http_host=http_host, # 如果 http_enabled=False, 这里会是 None
9694
http_port=http_port,
97-
http_callback_path=http_callback_path
95+
http_callback_path=http_callback_path,
9896
# maicore_token=maicore_token # 如果 core 需要 token
9997
)
10098

10199
# --- 插件加载 ---
102100
logger.info("加载插件...")
103-
plugin_manager = PluginManager(core, config.get("plugins", {})) # 传入插件全局配置
101+
plugin_manager = PluginManager(core, config.get("plugins", {})) # 传入插件全局配置
104102
# 构建插件目录的绝对或相对路径
105103
# 这里假设 main.py 在 VUP-NEXT 根目录运行
106-
plugin_dir = os.path.join(os.path.dirname(__file__), "src", "plugins")
104+
plugin_dir = os.path.join(os.path.dirname(__file__), "src", "plugins")
107105
await plugin_manager.load_plugins(plugin_dir)
108106
logger.info("插件加载完成。")
109107

110108
# --- 连接核心服务 ---
111-
await core.connect() # 连接 WebSocket 并启动 HTTP 服务器
109+
await core.connect() # 连接 WebSocket 并启动 HTTP 服务器
112110

113111
# --- 保持运行并处理退出信号 ---
114112
stop_event = asyncio.Event()
@@ -133,15 +131,16 @@ def signal_handler():
133131

134132
# --- 执行清理 ---
135133
logger.info("正在卸载插件...")
136-
await plugin_manager.unload_plugins() # 在断开连接前卸载插件
134+
await plugin_manager.unload_plugins() # 在断开连接前卸载插件
137135

138136
logger.info("正在关闭核心服务...")
139137
await core.disconnect()
140138
logger.info("VUP-NEXT 应用程序已关闭。")
141139

140+
142141
if __name__ == "__main__":
143142
try:
144143
asyncio.run(main())
145144
except KeyboardInterrupt:
146145
# 在 asyncio.run 之外捕获 KeyboardInterrupt (尽管上面的信号处理应该先触发)
147-
logger.info("检测到 KeyboardInterrupt,强制退出。")
146+
logger.info("检测到 KeyboardInterrupt,强制退出。")

src/core/plugin_manager.py

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import asyncio
22
import importlib
33
import inspect
4-
import logging
54
import os
65
import sys
76
from typing import TYPE_CHECKING, Dict, Any, Optional, Type
@@ -10,15 +9,17 @@
109
if TYPE_CHECKING:
1110
from .vup_next_core import VupNextCore
1211

13-
logger = logging.getLogger(__name__)
12+
from src.utils.logger import logger
13+
1414

1515
# --- 插件基类 (可选但推荐) ---
1616
class BasePlugin:
1717
"""所有插件的基础类,定义插件的基本接口。"""
18+
1819
# 添加一个类级别的标记属性
1920
_is_vup_next_plugin: bool = True
2021

21-
def __init__(self, core: 'VupNextCore', plugin_config: Dict[str, Any]):
22+
def __init__(self, core: "VupNextCore", plugin_config: Dict[str, Any]):
2223
"""
2324
初始化插件。
2425
@@ -28,7 +29,7 @@ def __init__(self, core: 'VupNextCore', plugin_config: Dict[str, Any]):
2829
"""
2930
self.core = core
3031
self.plugin_config = plugin_config
31-
self.logger = logging.getLogger(f"Plugin.{self.__class__.__name__}")
32+
self.logger = logger
3233
self.logger.info(f"初始化插件: {self.__class__.__name__}")
3334

3435
async def setup(self):
@@ -45,9 +46,11 @@ async def cleanup(self):
4546
# 子类应在此处实现清理逻辑
4647
pass
4748

49+
4850
class PluginManager:
4951
"""负责加载、管理和卸载插件。"""
50-
def __init__(self, core: 'VupNextCore', global_plugin_config: Dict[str, Any]):
52+
53+
def __init__(self, core: "VupNextCore", global_plugin_config: Dict[str, Any]):
5154
"""
5255
初始化插件管理器。
5356
@@ -59,7 +62,7 @@ def __init__(self, core: 'VupNextCore', global_plugin_config: Dict[str, Any]):
5962
self.global_plugin_config = global_plugin_config
6063
self.loaded_plugins: Dict[str, BasePlugin] = {}
6164
# 初始化 PluginManager 自己的 logger
62-
self.logger = logging.getLogger(__name__)
65+
self.logger = logger
6366
self.logger.debug("PluginManager 初始化完成")
6467

6568
async def load_plugins(self, plugin_dir: str = "src/plugins"):
@@ -86,8 +89,8 @@ async def load_plugins(self, plugin_dir: str = "src/plugins"):
8689
self.logger.debug(f"检测到潜在插件目录: {plugin_name}")
8790

8891
if not os.path.exists(plugin_module_file):
89-
self.logger.warning(f"在插件目录 '{plugin_name}' 中未找到主文件 'plugin.py',跳过。")
90-
continue
92+
self.logger.warning(f"在插件目录 '{plugin_name}' 中未找到主文件 'plugin.py',跳过。")
93+
continue
9194

9295
# --- 检查插件是否在配置中启用 ---
9396
is_enabled_key = f"enable_{plugin_name}"
@@ -99,7 +102,7 @@ async def load_plugins(self, plugin_dir: str = "src/plugins"):
99102
continue
100103

101104
# --- 加载插件模块 ---
102-
module = None # 初始化为 None
105+
module = None # 初始化为 None
103106
try:
104107
module_import_path = f"plugins.{plugin_name}.plugin"
105108
self.logger.debug(f"尝试导入模块: {module_import_path}")
@@ -108,19 +111,23 @@ async def load_plugins(self, plugin_dir: str = "src/plugins"):
108111

109112
# --- 查找并实例化插件类 (使用入口点) ---
110113
plugin_class: Optional[Type[BasePlugin]] = None
111-
entrypoint = None # 初始化为 None
112-
if hasattr(module, 'plugin_entrypoint'):
113-
entrypoint = getattr(module, 'plugin_entrypoint')
114-
self.logger.debug(f"在模块 '{module_import_path}' 中找到入口点 'plugin_entrypoint' 指向: {entrypoint}")
114+
entrypoint = None # 初始化为 None
115+
if hasattr(module, "plugin_entrypoint"):
116+
entrypoint = getattr(module, "plugin_entrypoint")
117+
self.logger.debug(
118+
f"在模块 '{module_import_path}' 中找到入口点 'plugin_entrypoint' 指向: {entrypoint}"
119+
)
115120
# 检查 entrypoint 是否是类,并且具有我们的标记属性
116-
if inspect.isclass(entrypoint) and getattr(entrypoint, '_is_vup_next_plugin', False):
121+
if inspect.isclass(entrypoint) and getattr(entrypoint, "_is_vup_next_plugin", False):
117122
plugin_class = entrypoint
118123
self.logger.debug(f"入口点验证成功 (通过标记属性),插件类为: {plugin_class.__name__}")
119124
else:
120-
self.logger.warning(f"模块 '{module_import_path}' 中的 'plugin_entrypoint' ({entrypoint}) 不是有效的插件类 (缺少标记或不是类)。")
125+
self.logger.warning(
126+
f"模块 '{module_import_path}' 中的 'plugin_entrypoint' ({entrypoint}) 不是有效的插件类 (缺少标记或不是类)。"
127+
)
121128
else:
122-
self.logger.warning(f"在模块 '{module_import_path}' 中未找到入口点 'plugin_entrypoint'。")
123-
129+
self.logger.warning(f"在模块 '{module_import_path}' 中未找到入口点 'plugin_entrypoint'。")
130+
124131
if plugin_class:
125132
plugin_specific_config = self.global_plugin_config.get(plugin_name, {})
126133
self.logger.debug(f"为插件 '{plugin_class.__name__}' 加载特定配置: {plugin_specific_config}")
@@ -135,7 +142,9 @@ async def load_plugins(self, plugin_dir: str = "src/plugins"):
135142
self.logger.warning(f"未能为模块 '{module_import_path}' 找到并验证有效的插件类。")
136143

137144
except ImportError as e:
138-
self.logger.error(f"导入插件模块 '{module_import_path if module else plugin_name}' 失败: {e}", exc_info=True)
145+
self.logger.error(
146+
f"导入插件模块 '{module_import_path if module else plugin_name}' 失败: {e}", exc_info=True
147+
)
139148
except Exception as e:
140149
self.logger.error(f"加载或设置插件 '{plugin_name}' 时发生错误: {e}", exc_info=True)
141150
# else: # 可以选择性地记录非插件目录的项
@@ -157,9 +166,9 @@ async def unload_plugins(self):
157166
if unload_tasks:
158167
results = await asyncio.gather(*unload_tasks, return_exceptions=True)
159168
for i, task in enumerate(unload_tasks):
160-
plugin_name = list(self.loaded_plugins.keys())[i]
161-
if isinstance(results[i], Exception):
162-
self.logger.error(f"清理插件 '{plugin_name}' 时出错: {results[i]}", exc_info=results[i])
163-
169+
plugin_name = list(self.loaded_plugins.keys())[i]
170+
if isinstance(results[i], Exception):
171+
self.logger.error(f"清理插件 '{plugin_name}' 时出错: {results[i]}", exc_info=results[i])
172+
164173
self.loaded_plugins.clear()
165-
self.logger.info("所有插件已卸载。")
174+
self.logger.info("所有插件已卸载。")

0 commit comments

Comments
 (0)