优化日志

This commit is contained in:
Windpicker-owo
2025-11-26 21:16:16 +08:00
parent e0157256b1
commit 0908fb50a0
100 changed files with 493 additions and 574 deletions

View File

@@ -67,7 +67,7 @@ async def get_replyer(
request_type=request_type,
)
except Exception as e:
logger.error(f"[GeneratorAPI] 获取回复器时发生意外错误: {e}", exc_info=True)
logger.error(f"[GeneratorAPI] 获取回复器时发生意外错误: {e}")
traceback.print_exc()
return None

View File

@@ -63,7 +63,6 @@ class PermissionAPI:
def set_permission_manager(self, manager: IPermissionManager):
self._permission_manager = manager
logger.info("权限管理器已设置")
def _ensure_manager(self):
if self._permission_manager is None:

View File

@@ -310,6 +310,15 @@ async def _send_to_target(
timestamp=current_time,
)
# Use readable display text so binary/base64 payloads are not stored directly
display_message_for_db = display_message or ""
if not display_message_for_db:
if message_type in {"emoji", "image", "voice", "video", "file"}:
# Leave empty to keep processed_plain_text (e.g., generated descriptions) instead of raw payloads
display_message_for_db = ""
elif isinstance(content, str):
display_message_for_db = content
sent_msg = await heart_fc_sender.send_message(
envelope,
chat_stream=target_stream,
@@ -317,7 +326,7 @@ async def _send_to_target(
storage_message=storage_message,
show_log=show_log,
thinking_start_time=current_time,
display_message=display_message or (content if isinstance(content, str) else ""),
display_message=display_message_for_db,
)
if sent_msg:

View File

@@ -92,7 +92,7 @@ class PluginStorage:
os.makedirs(directory)
logger.info(f"目录 '{directory}' 创建成功。")
except Exception as e:
logger.error(f"创建存储目录时发生错误: {e}", exc_info=True)
logger.error(f"创建存储目录时发生错误: {e}")
raise
def _load_data(self) -> None:
@@ -130,7 +130,7 @@ class PluginStorage:
self._dirty = False # 保存后重置标志
logger.debug(f"插件 '{self.name}' 的数据已成功保存到磁盘。")
except Exception as e:
logger.error(f"'{self.file_path}' 保存数据时发生错误: {e}", exc_info=True)
logger.error(f"'{self.file_path}' 保存数据时发生错误: {e}")
raise
def get(self, key: str, default: Any | None = None) -> Any:
@@ -203,5 +203,5 @@ def get_local_storage(name: str) -> "PluginStorage":
storage_instance = PluginStorageManager.get_storage(name)
return storage_instance
except Exception as e:
logger.critical(f"为插件 '{name}' 提供本地存储实例时发生严重错误: {e}", exc_info=True)
logger.critical(f"为插件 '{name}' 提供本地存储实例时发生严重错误: {e}")
raise

View File

@@ -365,7 +365,6 @@ class UnifiedScheduler:
logger.warning("调度器已在运行中")
return
logger.info("正在启动统一调度器...")
self._running = True
self._stopping = False
self._start_time = datetime.now()
@@ -384,14 +383,14 @@ class UnifiedScheduler:
except ImportError:
logger.warning("无法导入 event_manager事件触发功能将不可用")
logger.info("统一调度器已启动")
logger.debug("统一调度器已启动")
async def stop(self) -> None:
"""停止调度器(优雅关闭)"""
if not self._running:
return
logger.info("正在停止统一调度器...")
logger.debug("正在停止统一调度器...")
self._stopping = True
self._running = False
@@ -486,7 +485,7 @@ class UnifiedScheduler:
logger.debug("调度器主循环被取消")
break
except Exception as e:
logger.error(f"调度器主循环发生错误: {e}", exc_info=True)
logger.error(f"调度器主循环发生错误: {e}")
async def _deadlock_check_loop(self) -> None:
"""死锁检测循环"""
@@ -504,7 +503,7 @@ class UnifiedScheduler:
logger.debug("死锁检测循环被取消")
break
except Exception as e:
logger.error(f"死锁检测循环发生错误: {e}", exc_info=True)
logger.error(f"死锁检测循环发生错误: {e}")
# 继续运行,不因单次错误停止
async def _cleanup_loop(self) -> None:
@@ -522,7 +521,7 @@ class UnifiedScheduler:
logger.debug("清理循环被取消")
break
except Exception as e:
logger.error(f"清理循环发生错误: {e}", exc_info=True)
logger.error(f"清理循环发生错误: {e}")
# ==================== 任务触发逻辑 ====================
@@ -541,7 +540,7 @@ class UnifiedScheduler:
if should_trigger:
tasks_to_trigger.append(task)
except Exception as e:
logger.error(f"检查任务 {task.task_name} 触发条件时出错: {e}", exc_info=True)
logger.error(f"检查任务 {task.task_name} 触发条件时出错: {e}")
# 第二阶段:并发触发所有任务
if tasks_to_trigger:
@@ -604,7 +603,7 @@ class UnifiedScheduler:
result = condition_func()
return bool(result)
except Exception as e:
logger.error(f"执行任务 {task.task_name} 的自定义条件函数时出错: {e}", exc_info=True)
logger.error(f"执行任务 {task.task_name} 的自定义条件函数时出错: {e}")
return False
async def _trigger_tasks_concurrently(self, tasks: list[ScheduleTask]) -> None:
@@ -659,7 +658,7 @@ class UnifiedScheduler:
except Exception as e:
# 任务执行失败
logger.error(f"任务 {task.task_name} 执行失败: {e}", exc_info=True)
logger.error(f"任务 {task.task_name} 执行失败: {e}")
task.finish_execution(success=False, error=e)
self._total_failures += 1
@@ -695,7 +694,7 @@ class UnifiedScheduler:
)
return result
except Exception as e:
logger.error(f"执行任务 {task.task_name} 的回调函数时出错: {e}", exc_info=True)
logger.error(f"执行任务 {task.task_name} 的回调函数时出错: {e}")
raise
def _acquire_semaphore(self):
@@ -803,7 +802,7 @@ class UnifiedScheduler:
raise
except Exception as e:
logger.error(f"事件任务 {task.task_name} 执行失败: {e}", exc_info=True)
logger.error(f"事件任务 {task.task_name} 执行失败: {e}")
task.finish_execution(success=False, error=e)
self._total_failures += 1
@@ -823,7 +822,7 @@ class UnifiedScheduler:
except RecursionError:
logger.error("死锁检测发生递归错误,跳过本轮检测")
except Exception as e:
logger.error(f"死锁检测处理失败: {e}", exc_info=True)
logger.error(f"死锁检测处理失败: {e}")
async def _check_and_handle_deadlocks(self) -> None:
"""检查并处理死锁任务"""
@@ -847,7 +846,7 @@ class UnifiedScheduler:
try:
await self._cancel_task(task, reason="deadlock detected")
except Exception as e:
logger.error(f"取消任务 {task_name} 时出错: {e}", exc_info=True)
logger.error(f"取消任务 {task_name} 时出错: {e}")
# 强制清理
task._asyncio_task = None
task.status = TaskStatus.CANCELLED
@@ -884,7 +883,7 @@ class UnifiedScheduler:
break
except Exception as e:
logger.error(f"取消任务 {task.task_name} 时发生异常: {e}", exc_info=True)
logger.error(f"取消任务 {task.task_name} 时发生异常: {e}")
return False
# 第三阶段:强制清理
@@ -1095,7 +1094,7 @@ class UnifiedScheduler:
await exec_task
return task.status == TaskStatus.COMPLETED
except Exception as e:
logger.error(f"强制触发任务 {task.task_name} 失败: {e}", exc_info=True)
logger.error(f"强制触发任务 {task.task_name} 失败: {e}")
return False
async def pause_schedule(self, schedule_id: str) -> bool:
@@ -1293,19 +1292,13 @@ async def initialize_scheduler():
这个函数应该在 bot 启动时调用
"""
try:
logger.info("正在启动统一调度器...")
await unified_scheduler.start()
logger.info("统一调度器启动成功")
# 获取初始统计信息
stats = unified_scheduler.get_statistics()
logger.info(f"调度器状态: {stats}")
except Exception as e:
logger.error(f"启动统一调度器失败: {e}", exc_info=True)
logger.error(f"启动统一调度器失败: {e}")
raise
async def shutdown_scheduler():
"""关闭调度器
@@ -1329,4 +1322,4 @@ async def shutdown_scheduler():
logger.info("统一调度器已关闭")
except Exception as e:
logger.error(f"关闭统一调度器失败: {e}", exc_info=True)
logger.error(f"关闭统一调度器失败: {e}")

View File

@@ -513,7 +513,7 @@ class BaseAction(ABC):
return result
except Exception as e:
logger.error(f"{log_prefix} 调用时发生错误: {e}", exc_info=True)
logger.error(f"{log_prefix} 调用时发生错误: {e}")
return False, f"调用Action '{action_name}' 时发生错误: {e}"
@classmethod

View File

@@ -179,7 +179,7 @@ class BaseAdapter(MoFoxAdapterBase, ABC):
except asyncio.CancelledError:
break
except Exception as e:
logger.error(f"适配器 {self.adapter_name} 健康检查异常: {e}", exc_info=True)
logger.error(f"适配器 {self.adapter_name} 健康检查异常: {e}")
async def health_check(self) -> bool:
"""
@@ -204,7 +204,7 @@ class BaseAdapter(MoFoxAdapterBase, ABC):
await asyncio.sleep(2) # 等待一段时间再重连
await self.start()
except Exception as e:
logger.error(f"适配器 {self.adapter_name} 重连失败: {e}", exc_info=True)
logger.error(f"适配器 {self.adapter_name} 重连失败: {e}")
def get_subprocess_entry_path(self) -> Optional[Path]:
"""

View File

@@ -141,7 +141,7 @@ class PluginBase(ABC):
f.write(toml_str)
logger.info(f"{self.log_prefix} 已生成默认配置文件: {config_file_path}")
except OSError as e:
logger.error(f"{self.log_prefix} 保存默认配置文件失败: {e}", exc_info=True)
logger.error(f"{self.log_prefix} 保存默认配置文件失败: {e}")
def _backup_config_file(self, config_file_path: str) -> str:
"""备份配置文件到指定的 backup 子目录"""
@@ -158,7 +158,7 @@ class PluginBase(ABC):
logger.info(f"{self.log_prefix} 配置文件已备份到: {backup_path}")
return str(backup_path)
except Exception as e:
logger.error(f"{self.log_prefix} 备份配置文件失败: {e}", exc_info=True)
logger.error(f"{self.log_prefix} 备份配置文件失败: {e}")
return ""
def _synchronize_config(
@@ -285,7 +285,7 @@ class PluginBase(ABC):
f.write(toml_str)
logger.info(f"{self.log_prefix} 配置文件已保存: {config_file_path}")
except OSError as e:
logger.error(f"{self.log_prefix} 保存配置文件失败: {e}", exc_info=True)
logger.error(f"{self.log_prefix} 保存配置文件失败: {e}")
def _load_plugin_config(self): # sourcery skip: extract-method
"""
@@ -314,7 +314,7 @@ class PluginBase(ABC):
shutil.move(plugin_config_path, user_config_path)
logger.info(f"{self.log_prefix} 已将配置文件从 {plugin_config_path} 迁移到 {user_config_path}")
except OSError as e:
logger.error(f"{self.log_prefix} 迁移配置文件失败: {e}", exc_info=True)
logger.error(f"{self.log_prefix} 迁移配置文件失败: {e}")
# 如果用户配置文件仍然不存在,生成默认的
if not os.path.exists(user_config_path):
@@ -333,7 +333,7 @@ class PluginBase(ABC):
with open(user_config_path, encoding="utf-8") as f:
user_config: dict[str, Any] = toml.load(f) or {}
except Exception as e:
logger.error(f"{self.log_prefix} 加载用户配置文件 {user_config_path} 失败: {e}", exc_info=True)
logger.error(f"{self.log_prefix} 加载用户配置文件 {user_config_path} 失败: {e}")
self.config = self._generate_config_from_schema() # 加载失败时使用默认 schema
return

View File

@@ -384,7 +384,7 @@ def create_plus_command_adapter(plus_command_class):
try:
return await self.plus_command.execute(command_args)
except Exception as e:
logger.error(f"执行命令时出错: {e}", exc_info=True)
logger.error(f"执行命令时出错: {e}")
return False, f"命令执行出错: {e!s}", self.intercept_message
return AdapterClass
@@ -443,7 +443,7 @@ def create_legacy_command_adapter(legacy_command_class):
# 旧的execute不接收args参数
return await self.legacy_command.execute()
except Exception as e:
logger.error(f"执行旧版命令 '{self.command_name}' 时出错: {e}", exc_info=True)
logger.error(f"执行旧版命令 '{self.command_name}' 时出错: {e}")
return False, f"命令执行出错: {e!s}", self.intercept_message
return LegacyAdapter

View File

@@ -28,8 +28,32 @@ logger = get_logger("adapter_manager")
def _load_class(module_name: str, class_name: str):
"""
从模块加载类。
有时插件加载器会将适配器类注册到包名下(例如 ``src.plugins.built_in.napcat_adapter``
而实际的类定义在 ``plugin.py`` 中。当子进程仅导入包时,该属性缺失会引发 AttributeError。
该辅助函数现在回退到 ``<module>.plugin`` 以支持这种布局。
"""
module = importlib.import_module(module_name)
return getattr(module, class_name)
if hasattr(module, class_name):
return getattr(module, class_name)
# Fallback for packages that keep implementations in plugin.py
try:
plugin_module = importlib.import_module(f"{module_name}.plugin")
if hasattr(plugin_module, class_name):
return getattr(plugin_module, class_name)
except ModuleNotFoundError:
pass
except Exception:
logger.error(
f"Failed to load class {class_name} from fallback module {module_name}.plugin",
exc_info=True,
)
# If we reach here, the class is truly missing
raise AttributeError(f"module '{module_name}' has no attribute '{class_name}'")
def _adapter_process_entry(
@@ -127,7 +151,7 @@ class AdapterProcess:
return True
except Exception as e:
logger.error(f"启动适配器子进程 {self.adapter_name} 失败: {e}", exc_info=True)
logger.error(f"启动适配器子进程 {self.adapter_name} 失败: {e}")
return False
async def stop(self) -> None:
@@ -154,7 +178,7 @@ class AdapterProcess:
self.process.join()
except Exception as e:
logger.error(f"停止适配器子进程 {self.adapter_name} 时发生错误: {e}", exc_info=True)
logger.error(f"停止适配器子进程 {self.adapter_name} 时发生错误: {e}")
finally:
self.process = None
self._incoming_queue = None
@@ -258,7 +282,7 @@ class AdapterManager:
return True
except Exception as e:
logger.error(f"启动适配器 {adapter_name} 失败: {e}", exc_info=True)
logger.error(f"启动适配器 {adapter_name} 失败: {e}")
return False
async def stop_adapter(self, adapter_name: str) -> None:
@@ -280,7 +304,7 @@ class AdapterManager:
await adapter.stop()
logger.info(f"适配器 {adapter_name} 已从主进程中停止")
except Exception as e:
logger.error(f"停止适配器 {adapter_name} 时出错: {e}", exc_info=True)
logger.error(f"停止适配器 {adapter_name} 时出错: {e}")
async def start_all_adapters(self) -> None:
"""启动所有已注册的适配器"""
@@ -358,4 +382,4 @@ def get_adapter_manager() -> AdapterManager:
return _adapter_manager
__all__ = ["AdapterManager", "AdapterProcess", "get_adapter_manager"]
__all__ = ["AdapterManager", "AdapterProcess", "get_adapter_manager"]

View File

@@ -428,7 +428,7 @@ class ComponentRegistry:
return True
except Exception as e:
logger.error(f"注册路由组件 '{router_info.name}' 时出错: {e}", exc_info=True)
logger.error(f"注册路由组件 '{router_info.name}' 时出错: {e}")
return False
def _register_adapter_component(self, adapter_info: AdapterInfo, adapter_class: type[BaseAdapter]) -> bool:

View File

@@ -342,7 +342,7 @@ class EventManager:
# 使用 create_task 异步执行,避免死锁
asyncio.create_task(self._scheduler_callback(event_name, params))
except Exception as e:
logger.error(f"调用 scheduler 回调时出错: {e}", exc_info=True)
logger.error(f"调用 scheduler 回调时出错: {e}")
timeout = handler_timeout if handler_timeout is not None else self._default_handler_timeout
concurrency = max_concurrency if max_concurrency is not None else self._default_handler_concurrency

View File

@@ -30,11 +30,11 @@ class PermissionManager(IPermissionManager):
"""异步初始化数据库连接"""
self.engine = await get_engine()
self.SessionLocal = async_sessionmaker(bind=self.engine)
logger.info("权限管理器初始化完成")
logger.debug("权限管理器初始化完成")
def _load_master_users(self):
"""从配置文件加载Master用户列表"""
logger.info("开始从配置文件加载Master用户...")
logger.debug("开始从配置文件加载Master用户...")
try:
master_users_config = global_config.permission.master_users
if not isinstance(master_users_config, list):
@@ -61,7 +61,7 @@ class PermissionManager(IPermissionManager):
logger.info(f"成功加载 {len(self._master_users)} 个Master用户")
except Exception as e:
logger.error(f"加载Master用户配置时发生严重错误: {e}", exc_info=True)
logger.error(f"加载Master用户配置时发生严重错误: {e}")
self._master_users = set()
def reload_master_users(self):

View File

@@ -179,7 +179,7 @@ class PluginManager:
error_msg = f"未知错误: {e!s}"
self.failed_plugins[plugin_name] = error_msg
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
logger.debug("详细错误信息: ", exc_info=True)
logger.debug("详细错误信息: ")
return False, 1
async def _register_adapter_components(self, plugin_name: str, plugin_instance: PluginBase) -> None:
@@ -238,7 +238,7 @@ class PluginManager:
)
except Exception as e:
logger.error(f"处理插件 '{plugin_name}' 的适配器组件时出错: {e}", exc_info=True)
logger.error(f"处理插件 '{plugin_name}' 的适配器组件时出错: {e}")
async def remove_registered_plugin(self, plugin_name: str) -> bool:
"""
@@ -682,7 +682,7 @@ class PluginManager:
asyncio.run(component_registry.unregister_plugin(plugin_name))
except Exception as e: # 捕获并记录卸载阶段协程调用错误
logger.debug(
f"卸载插件时调用 component_registry.unregister_plugin 失败: {e}", exc_info=True
f"卸载插件时调用 component_registry.unregister_plugin 失败: {e}"
)
# 从已加载插件中移除
@@ -700,7 +700,7 @@ class PluginManager:
return True
except Exception as e:
logger.error(f"❌ 插件卸载失败: {plugin_name} - {e!s}", exc_info=True)
logger.error(f"❌ 插件卸载失败: {plugin_name} - {e!s}")
return False