from loguru import logger from typing import Dict, Any, Tuple, Optional, List from base.plugin_common.plugin_interface import PluginInterface, PluginStatus from base.event_system.event_manager import EventManager # 使用正确的事件类型导入 from base.event_system.events.plugin_events import PluginCallStartEvent, PluginCallEndEvent, PluginCallErrorEvent # 数据库导入 from db.stats_db import StatsDBOperator from db.connection import DBConnectionManager class StatsCollectorPlugin(PluginInterface): """统计收集插件""" @property def name(self) -> str: return "指令记录" @property def version(self) -> str: return "1.0.0" @property def description(self) -> str: return "群聊指令数据记录" @property def author(self) -> str: return "Liuwei" @property def command_prefix(self) -> Optional[str]: return "#" @property def commands(self) -> List[str]: return [] def __init__(self): super().__init__() self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 默认配置 self.config = { "enable": True, "record_all_plugins": True, # 是否记录所有插件的调用 "excluded_plugins": [], # 排除的插件列表 } self.event_manager = EventManager.get_instance() self.db_manager = DBConnectionManager.get_instance() self.stats_db = StatsDBOperator(self.db_manager) # 注册功能权限 def initialize(self, config: Dict[str, Any]) -> bool: """初始化插件""" if config: self.config.update(config) if not self.config["enable"]: self.LOG.info("统计收集插件已禁用") return False # 注册事件处理器 self.event_manager.register(PluginCallStartEvent, self.handle_plugin_call_start) self.event_manager.register(PluginCallEndEvent, self.handle_plugin_call_end) self.event_manager.register(PluginCallErrorEvent, self.handle_plugin_error) return True def handle_plugin_call_start(self, event: PluginCallStartEvent) -> None: """处理插件调用开始事件""" # 检查是否需要记录该插件 if not self._should_record_plugin(event.plugin_name): return # 记录开始时间和相关信息 self.LOG.debug(f"记录插件调用开始: {event.plugin_name} - {event.command}") def handle_plugin_call_end(self, event: PluginCallEndEvent) -> None: """处理插件调用结束事件""" # 检查是否需要记录该插件 if not self._should_record_plugin(event.plugin_name): return # 记录统计数据 try: # 确保使用正确的属性名 self.stats_db.record_plugin_call( plugin_name=event.plugin_name, command=event.command, user_id=event.user_id, group_id=event.group_id, success=event.process_result, process_time_ms=event.process_time ) self.LOG.debug( f"记录插件调用结束: {event.plugin_name} - {event.command} - 成功: {event.process_result} - 处理时间: {event.process_time}ms") except Exception as e: self.LOG.error(f"记录插件调用统计数据出错: {e}") def handle_plugin_error(self, event: PluginCallErrorEvent) -> None: """处理插件调用错误事件""" # 检查是否需要记录该插件 if not self._should_record_plugin(event.plugin_name): return # 记录错误信息 try: self.stats_db.record_error( plugin_name=event.plugin_name, command=event.command, user_id=event.user_id, group_id=event.group_id, error_message=event.error_message, stack_trace=event.stack_trace ) self.LOG.debug(f"记录插件调用错误: {event.plugin_name} - {event.command} - {event.error_message}") except Exception as e: self.LOG.error(f"记录插件错误信息出错: {e}") def _should_record_plugin(self, plugin_name: str) -> bool: """检查是否应该记录该插件的调用""" if not self.config["record_all_plugins"]: return False if plugin_name in self.config["excluded_plugins"]: return False # 不记录自身的调用 if plugin_name == self.name: return False return True def match_command(self, content: str) -> bool: """匹配命令""" # 该插件不处理用户消息 return False def process_message(self, message: Dict[str, Any]) -> Tuple[bool, str]: """处理消息""" # 该插件不处理用户消息 return False, "" def shutdown(self) -> None: """关闭插件""" # 取消注册事件处理器 self.event_manager.unregister(PluginCallStartEvent, self.handle_plugin_call_start) self.event_manager.unregister(PluginCallEndEvent, self.handle_plugin_call_end) self.event_manager.unregister(PluginCallErrorEvent, self.handle_plugin_error) self.LOG.info("统计收集插件已关闭") def start(self) -> bool: """启动插件""" self.LOG.info(f"[{self.name}] 插件已启动") self.status = PluginStatus.RUNNING return True def stop(self) -> bool: """停止插件""" self.LOG.info(f"[{self.name}] 插件已停止") self.status = PluginStatus.STOPPED return True