调整指令信息

This commit is contained in:
liuwei
2025-03-18 17:53:25 +08:00
parent 1d7ee9f953
commit 345439be90
4 changed files with 121 additions and 154 deletions

View File

@@ -2,12 +2,15 @@ import logging
from typing import Dict, List, Type, Callable, Any from typing import Dict, List, Type, Callable, Any
from threading import Lock from threading import Lock
class Event: class Event:
"""事件基类""" """事件基类"""
def __init__(self, **kwargs): def __init__(self, **kwargs):
for key, value in kwargs.items(): for key, value in kwargs.items():
setattr(self, key, value) setattr(self, key, value)
class EventManager: class EventManager:
"""事件管理器,单例模式""" """事件管理器,单例模式"""
_instance = None _instance = None

View File

@@ -1,74 +1,58 @@
from dataclasses import dataclass
from typing import Dict, Any, Optional
from datetime import datetime
from event_system.event_manager import Event from event_system.event_manager import Event
from typing import Optional, Dict, Any
@dataclass
class PluginCallStartEvent(Event): class PluginCallStartEvent(Event):
"""插件调用开始事件""" """插件调用开始事件"""
def __init__(self, plugin_name: str, command: str, user_id: str, plugin_name: str # 插件名称
group_id: Optional[str] = None, **kwargs): command: str # 触发的命令
""" full_command: str # 完整命令内容
Args: user_id: str # 用户ID
plugin_name: 插件名称 group_id: Optional[str] = None # 群组ID私聊为None
command: 触发的命令 is_group: bool = False # 是否群聊
user_id: 用户ID message: Dict[str, Any] = None # 原始消息内容
group_id: 群组ID私聊为None timestamp: datetime = None # 事件时间戳
"""
super().__init__( def __post_init__(self):
plugin_name=plugin_name, if self.timestamp is None:
command=command, self.timestamp = datetime.now()
user_id=user_id,
group_id=group_id,
**kwargs
)
@dataclass
class PluginCallEndEvent(Event): class PluginCallEndEvent(Event):
"""插件调用结束事件""" """插件调用结束事件"""
def __init__(self, plugin_name: str, command: str, user_id: str, plugin_name: str # 插件名称
group_id: Optional[str], success: bool, command: str # 触发的命令
process_time_ms: float, result: Any = None, **kwargs): user_id: str # 用户ID
""" group_id: Optional[str] = None # 群组ID私聊为None
Args: is_group: bool = False # 是否群聊
plugin_name: 插件名称 process_result: bool = True # 处理结果True成功False失败
command: 触发的命令 result_message: Optional[str] = None # 处理结果消息
user_id: 用户ID process_time: int = 0 # 处理耗时(毫秒)
group_id: 群组ID私聊为None timestamp: datetime = None # 事件时间戳
success: 是否调用成功
process_time_ms: 处理时间(毫秒) def __post_init__(self):
result: 处理结果 if self.timestamp is None:
""" self.timestamp = datetime.now()
super().__init__(
plugin_name=plugin_name,
command=command,
user_id=user_id,
group_id=group_id,
success=success,
process_time_ms=process_time_ms,
result=result,
**kwargs
)
class PluginErrorEvent(Event): @dataclass
"""插件错误事件""" class PluginCallErrorEvent(Event):
def __init__(self, plugin_name: str, command: str, user_id: str, """插件调用错误事件"""
group_id: Optional[str], error_message: str, plugin_name: str # 插件名称
stack_trace: Optional[str] = None, **kwargs): command: str # 触发的命令
""" user_id: str # 用户ID
Args: group_id: Optional[str] = None # 群组ID私聊为None
plugin_name: 插件名称 is_group: bool = False # 是否群聊
command: 触发的命令 error_message: str # 错误信息
user_id: 用户ID stack_trace: Optional[str] = None # 堆栈跟踪
group_id: 群组ID私聊为None process_time: int = 0 # 处理耗时(毫秒)
error_message: 错误信息 timestamp: datetime = None # 事件时间戳
stack_trace: 堆栈跟踪
""" def __post_init__(self):
super().__init__( if self.timestamp is None:
plugin_name=plugin_name, self.timestamp = datetime.now()
command=command,
user_id=user_id,
group_id=group_id,
error_message=error_message,
stack_trace=stack_trace,
**kwargs
)

View File

@@ -1,40 +0,0 @@
from dataclasses import dataclass
from typing import Optional
from datetime import datetime
from event_system.event import Event
@dataclass
class PluginCallStartEvent(Event):
"""插件调用开始事件"""
plugin_name: str
command: str
user_id: str
group_id: Optional[str]
start_time: datetime
@dataclass
class PluginCallEndEvent(Event):
"""插件调用结束事件"""
plugin_name: str
command: str
user_id: str
group_id: Optional[str]
start_time: datetime
end_time: datetime
success: bool
response: Optional[str]
@dataclass
class PluginCallErrorEvent(Event):
"""插件调用错误事件"""
plugin_name: str
command: str
user_id: str
group_id: Optional[str]
start_time: datetime
error_message: str
stack_trace: Optional[str]

View File

@@ -1,27 +1,46 @@
import logging import logging
import time import time
from typing import Dict, Any, Tuple, Optional from typing import Dict, Any, Tuple, Optional, List
from datetime import datetime from datetime import datetime
from plugin_common.plugin_interface import PluginInterface from plugin_common.plugin_interface import PluginInterface
from event_system.event_manager import EventManager from event_system.event_manager import EventManager
# 修正导入,使用与装饰器相同的事件类型 # 使用正确的事件类型导入
from event_system.events.plugin_events import PluginCallStartEvent, PluginCallEndEvent, PluginCallErrorEvent from event_system.events.plugin_events import PluginCallStartEvent, PluginCallEndEvent, PluginCallErrorEvent
# 数据库导入
from db.stats_db import StatsDBOperator from db.stats_db import StatsDBOperator
from db.db_manager import DBConnectionManager from db.connection import DBConnectionManager
from job_decorators import register_job_decorator
from .decorators import plugin_stats_decorator
class StatsCollectorPlugin(PluginInterface): class StatsCollectorPlugin(PluginInterface):
"""统计收集插件""" """统计收集插件"""
@property
def name(self) -> str:
return "command collector"
@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): def __init__(self):
self.name = "统计收集器"
self.version = "1.0.0"
self.description = "收集插件调用统计数据"
self.author = "Trae AI"
self.logger = logging.getLogger("StatsCollector") self.logger = logging.getLogger("StatsCollector")
# 默认配置 # 默认配置
@@ -32,13 +51,9 @@ class StatsCollectorPlugin(PluginInterface):
} }
self.event_manager = EventManager.get_instance() self.event_manager = EventManager.get_instance()
# 修正获取数据库连接管理器的方式 self.db_manager = DBConnectionManager()
self.db_manager = DBConnectionManager.get_instance()
self.stats_db = StatsDBOperator(self.db_manager) self.stats_db = StatsDBOperator(self.db_manager)
# 用于临时存储插件调用开始时间的字典
self.plugin_call_start_times = {}
def initialize(self, config: Dict[str, Any]) -> bool: def initialize(self, config: Dict[str, Any]) -> bool:
"""初始化插件""" """初始化插件"""
if config: if config:
@@ -63,7 +78,6 @@ class StatsCollectorPlugin(PluginInterface):
return return
# 记录开始时间和相关信息 # 记录开始时间和相关信息
# 注意plugin_events.py 中的事件结构与 stats_events.py 不同
self.logger.debug(f"记录插件调用开始: {event.plugin_name} - {event.command}") self.logger.debug(f"记录插件调用开始: {event.plugin_name} - {event.command}")
def handle_plugin_call_end(self, event: PluginCallEndEvent) -> None: def handle_plugin_call_end(self, event: PluginCallEndEvent) -> None:
@@ -74,15 +88,17 @@ class StatsCollectorPlugin(PluginInterface):
# 记录统计数据 # 记录统计数据
try: try:
# 确保使用正确的属性名
self.stats_db.record_plugin_call( self.stats_db.record_plugin_call(
plugin_name=event.plugin_name, plugin_name=event.plugin_name,
command=event.command, command=event.command,
user_id=event.user_id, user_id=event.user_id,
group_id=event.group_id, group_id=event.group_id,
success=event.process_result, # 注意字段名不同 success=event.process_result,
process_time_ms=event.process_time # 注意字段名不同 process_time_ms=event.process_time
) )
self.logger.debug(f"记录插件调用结束: {event.plugin_name} - {event.command} - 成功: {event.process_result} - 处理时间: {event.process_time}ms") self.logger.debug(
f"记录插件调用结束: {event.plugin_name} - {event.command} - 成功: {event.process_result} - 处理时间: {event.process_time}ms")
except Exception as e: except Exception as e:
self.logger.error(f"记录插件调用统计数据出错: {e}") self.logger.error(f"记录插件调用统计数据出错: {e}")
@@ -114,6 +130,10 @@ class StatsCollectorPlugin(PluginInterface):
if plugin_name in self.config["excluded_plugins"]: if plugin_name in self.config["excluded_plugins"]:
return False return False
# 不记录自身的调用
if plugin_name == self.name:
return False
return True return True
def match_command(self, content: str) -> bool: def match_command(self, content: str) -> bool: