优化日志
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]:
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user