diff --git a/bots/commands/stats.py b/bots/commands/stats.py index c5f2c05..25d300b 100644 --- a/bots/commands/stats.py +++ b/bots/commands/stats.py @@ -1,151 +1,87 @@ # -*- coding: utf-8 -*- """ Административные команды: !stats, !status, !clean. -- !stats – статистика работы бота (сообщения, файлы, AI-запросы, ошибки, uptime). -- !status – проверка состояния сервисов (GigaChat, PostgreSQL, Qdrant, диск). -- !clean – очистка временной директории. - -Изменения для PostgreSQL: -- Замена `conn.ping()` на `conn.execute("SELECT 1")` в команде !status. -- Обновлены тексты сообщений (MariaDB → PostgreSQL). +Используют RAGClient. """ import os import shutil import logging from datetime import datetime - from core.commands.base import Command logger = logging.getLogger(__name__) class StatsCommand(Command): - """Показывает статистику работы бота (только для администраторов).""" - name = "!stats" - aliases = ["/stats", "!статистика", "/статистика", "!стат", "/стат"] + aliases = ["/stats"] permission = "admin" async def execute(self, msg, args: str, user_jid: str, room_jid: str = None): - """ - Выводит: - - uptime бота - - количество обработанных сообщений - - количество AI-запросов - - количество обработанных файлов - - количество ошибок - - количество документов в базе знаний (с учётом контекста) - """ if not self.check_permission(user_jid): reply = msg.reply("⛔ Нет прав.") - if reply: - reply.send() # исправлено - else: - logger.error("Не удалось отправить сообщение о недостатке прав (stats)") + if reply: reply.send() return - - # Время работы бота - uptime = datetime.now() - self.bot.start_time - - # Получение метрик из MetricsHandler - stats = self.bot.metrics_handler.get() - - # Количество доступных документов в БЗ (личные/комнатные + глобальные) - sources = await self.bot.kb.get_available_sources(user_jid, room_jid) - - response = ( - f"📊 **Статистика бота {self.bot.config.name}**\n" - f"⏱ Uptime: {str(uptime).split('.')[0]}\n" - f"💬 Сообщений: {stats.get('messages_total', 0)}\n" - f"🤖 AI запросов: {stats.get('ai_requests', 0)}\n" - f"📁 Файлов обработано: {stats.get('files_processed', 0)}\n" - f"❌ Ошибок: {stats.get('errors_total', 0)}\n" - f"📚 Документов в БЗ: {len(sources)}" - ) - reply = msg.reply(response) + try: + stats = await self.bot.rag_client.get_stats() + uptime = datetime.now() - self.bot.start_time + response = ( + f"📊 Статистика бота {self.bot.config.name}\n" + f"⏱ Uptime: {str(uptime).split('.')[0]}\n" + f"📚 Документов в БЗ: {stats.get('documents', 0)}\n" + f"⏱ Время работы сервера: {stats.get('uptime', 0):.0f} сек" + ) + reply = msg.reply(response) + except Exception as e: + logger.exception(f"Ошибка в !stats: {e}") + reply = msg.reply(f"❌ Ошибка получения статистики: {e}") if reply: - reply.send() # исправлено - else: - logger.error("Не удалось отправить статистику") + reply.send() def get_help(self) -> str: - return "Показывает статистику работы бота (админ)." + return "Показывает статистику (админ)." class StatusCommand(Command): - """Проверяет состояние всех внешних сервисов (административная команда).""" - name = "!status" - aliases = ["/status", "!статус", "/статус"] + aliases = ["/status"] permission = "admin" async def execute(self, msg, args: str, user_jid: str, room_jid: str = None): if not self.check_permission(user_jid): reply = msg.reply("⛔ Нет прав.") - if reply: - reply.send() # исправлено - else: - logger.error("Не удалось отправить сообщение о недостатке прав (stats)") + if reply: reply.send() return - - # --- GigaChat --- try: - # Простой запрос для проверки доступности API - await self.bot.giga.chat([], "ping", system_prompt=None, file_id=None, temperature=0.1) - ai_status = "✅ GigaChat Online" + health = await self.bot.rag_client.health_check() + if health: + status = "✅ Все сервисы работают" + else: + status = "⚠️ Некоторые сервисы недоступны" + reply = msg.reply(f"🛰 Статус бота: {status}") except Exception as e: - ai_status = f"❌ GigaChat Offline: {e}" - - # --- PostgreSQL (asyncpg) --- - try: - async with self.bot.db.pool.acquire() as conn: - # В asyncpg нет метода ping(), используем SELECT 1 - await conn.execute("SELECT 1") - db_status = "✅ PostgreSQL Online" - except Exception as e: - db_status = f"❌ PostgreSQL Error: {e}" - - # --- Qdrant --- - try: - self.bot.qdrant.client.get_collection(self.bot.qdrant.collection_name) - qd_status = "✅ Qdrant Online" - except Exception as e: - qd_status = f"❌ Qdrant Error: {e}" - - # --- Дисковое пространство (временная директория) --- - total, used, free = shutil.disk_usage(self.bot.config.temp_dir) - disk_info = f"💾 Диск: {used // (2**20)}MB / {total // (2**20)}MB" - - full_status = f"🛰 **СТАТУС БОТА**\n{ai_status}\n{db_status}\n{qd_status}\n{disk_info}" - reply = msg.reply(full_status) + logger.exception(f"Ошибка в !status: {e}") + reply = msg.reply(f"❌ Ошибка проверки статуса: {e}") if reply: - reply.send() # исправлено - else: - logger.error("Не удалось отправить статус") + reply.send() def get_help(self) -> str: - return "Проверяет состояние сервисов (GigaChat, PostgreSQL, Qdrant, диск) – админ." + return "Проверяет состояние сервисов (админ)." class CleanCommand(Command): - """Очищает временную директорию бота (temp_dir).""" - name = "!clean" - aliases = ["/clean", "!очистка", "/очистка"] + aliases = ["/clean"] permission = "admin" async def execute(self, msg, args: str, user_jid: str, room_jid: str = None): if not self.check_permission(user_jid): reply = msg.reply("⛔ Нет прав.") - if reply: - reply.send() # исправлено - else: - logger.error("Не удалось отправить сообщение о недостатке прав (stats)") + if reply: reply.send() return - - count = 0 temp_dir = self.bot.config.temp_dir + count = 0 for f in os.listdir(temp_dir): try: p = os.path.join(temp_dir, f) @@ -154,13 +90,11 @@ class CleanCommand(Command): elif os.path.isdir(p): shutil.rmtree(p) count += 1 - except Exception: + except: pass reply = msg.reply(f"🧹 Удалено объектов из temp_dir: {count}") if reply: - reply.send() # исправлено - else: - logger.error("Не удалось отправить отчёт об очистке") + reply.send() def get_help(self) -> str: - return "Очищает временную директорию бота (админ)." \ No newline at end of file + return "Очищает временную директорию (админ)." \ No newline at end of file