""" 性能监控插件 提供系统性能统计和监控功能 """ import asyncio import time import os from utils.plugin_base import PluginBase from utils.decorators import on_text_message, schedule from loguru import logger class PerformanceMonitor(PluginBase): """性能监控插件""" # 插件元数据 description = "系统性能监控和统计" author = "System" version = "1.0.0" def __init__(self): super().__init__() self.start_time = time.time() self.last_stats_time = time.time() self.last_message_count = 0 async def async_init(self): """插件异步初始化""" logger.info("性能监控插件已加载") @on_text_message(priority=90) async def handle_stats_command(self, bot, message: dict): """处理性能统计命令""" content = message.get("Content", "").strip() from_wxid = message.get("FromWxid", "") # 检查是否是管理员 import tomllib with open("main_config.toml", "rb") as f: config = tomllib.load(f) admins = config.get("Bot", {}).get("admins", []) sender_wxid = message.get("SenderWxid", from_wxid) if sender_wxid not in admins: return if content in ["/性能", "/stats", "/状态"]: stats_msg = await self._get_performance_stats(bot) await bot.send_text(from_wxid, stats_msg) return False # 阻止其他插件处理 @schedule('interval', minutes=30) async def log_performance_stats(self, bot): """定期记录性能统计""" try: stats = await self._get_performance_data() logger.info(f"性能统计: 消息队列={stats['queue_size']}/{stats['queue_max']}, " f"处理速率={stats['message_rate']:.1f}/min, " f"总消息={stats['total_messages']}, " f"已处理={stats['processed_messages']}") except Exception as e: logger.error(f"性能统计记录失败: {e}") async def _get_performance_stats(self, bot) -> str: """获取性能统计信息""" try: stats = await self._get_performance_data() # 格式化统计信息 uptime_hours = (time.time() - self.start_time) / 3600 msg = f"""📊 系统性能统计 🕐 运行时间: {uptime_hours:.1f} 小时 📨 消息统计: • 总消息数: {stats['total_messages']} • 已处理: {stats['processed_messages']} • 已过滤: {stats['filtered_messages']} • 处理率: {stats['process_rate']:.1%} • 过滤率: {stats['filter_rate']:.1%} ⚡ 性能指标: • 消息队列: {stats['queue_size']} / {stats['queue_max']} • 处理速率: {stats['message_rate']:.1f} 消息/分钟 • 熔断器状态: {'🔴 开启' if stats['circuit_breaker_open'] else '🟢 正常'} 🔧 配置状态: • 控制台日志: {'✅ 启用' if stats['console_log_enabled'] else '❌ 禁用'} • 日志采样率: {stats['log_sampling_rate']:.0%} • 最大并发: {stats['max_concurrency']} • 过滤模式: {stats['ignore_mode']}""" return msg except Exception as e: logger.error(f"获取性能统计失败: {e}") return f"❌ 获取性能统计失败: {str(e)}" async def _get_performance_data(self) -> dict: """获取性能数据""" # 系统资源(简化版本,不依赖psutil) try: import platform system_info = platform.system() # 简单的进程信息 import os pid = os.getpid() cpu_percent = 0.0 # 暂时设为0,避免依赖psutil memory_percent = 0.0 memory_mb = 0.0 except: cpu_percent = 0.0 memory_percent = 0.0 memory_mb = 0.0 # 获取 HookBot 统计 from utils.plugin_manager import PluginManager bot_service = getattr(PluginManager(), '_bot_service', None) if bot_service and hasattr(bot_service, 'hookbot') and bot_service.hookbot: hookbot_stats = bot_service.hookbot.get_stats() queue_size = bot_service.message_queue.qsize() if bot_service.message_queue else 0 queue_max = bot_service.queue_config.get("max_size", 1000) circuit_breaker_open = bot_service.circuit_breaker_open max_concurrency = bot_service.concurrency_config.get("plugin_max_concurrency", 8) ignore_mode = bot_service.hookbot.ignore_mode else: hookbot_stats = { "total_messages": 0, "processed_messages": 0, "filtered_messages": 0, "process_rate": 0, "filter_rate": 0 } queue_size = 0 queue_max = 1000 circuit_breaker_open = False max_concurrency = 8 ignore_mode = "None" # 计算消息处理速率 current_time = time.time() time_diff = current_time - self.last_stats_time message_diff = hookbot_stats["total_messages"] - self.last_message_count if time_diff > 0: message_rate = (message_diff / time_diff) * 60 # 每分钟消息数 else: message_rate = 0 self.last_stats_time = current_time self.last_message_count = hookbot_stats["total_messages"] # 读取配置 try: import tomllib with open("main_config.toml", "rb") as f: config = tomllib.load(f) perf_config = config.get("Performance", {}) console_log_enabled = perf_config.get("log_console_enabled", True) log_sampling_rate = perf_config.get("log_sampling_rate", 1.0) except: console_log_enabled = True log_sampling_rate = 1.0 return { "queue_size": queue_size, "queue_max": queue_max, "message_rate": message_rate, "circuit_breaker_open": circuit_breaker_open, "console_log_enabled": console_log_enabled, "log_sampling_rate": log_sampling_rate, "max_concurrency": max_concurrency, "ignore_mode": ignore_mode, **hookbot_stats }