Files
fckbot/bots/commands/stats.py
Markov Andrey 63900feece Update 86 files
- /rag/commands/expert.py
- /core/services/__init__.py
- /core/services/embedding_service.py
- /core/services/file_service.py
- /core/services/giga_client.py
- /core/services/kb_service.py
- /core/services/postgres_service.py
- /core/services/qdrant_service.py
- /core/services/reranker_service.py
- /core/functions/__init__.py
- /core/functions/check_consistency.py
- /core/functions/check_spelling.py
- /core/functions/critique_answer.py
- /core/functions/expand_query.py
- /core/functions/extract_metrics.py
- /core/functions/file_processor.py
- /core/functions/generate_document.py
- /core/functions/intent_classify.py
- /core/functions/rerank_context.py
- /core/functions/summarize_document.py
- /core/utils/__init__.py
- /core/utils/arg_parser.py
- /core/utils/config_loader.py
- /core/utils/layout_converter.py
- /core/utils/logger.py
- /core/utils/text_utils.py
- /core/utils/web_utils.py
- /bots/commands/__init__.py
- /bots/commands/base.py
- /bots/commands/create.py
- /core/commands/global_remove.py
- /core/commands/help.py
- /core/commands/info.py
- /core/commands/kb.py
- /core/commands/learn.py
- /core/commands/other.py
- /core/commands/registry.py
- /core/commands/stats.py
- /core/commands/template.py
- /core/handlers/__init__.py
- /core/handlers/message_handler.py
- /core/workers/__init__.py
- /core/workers/indexing_worker.py
- /core/xmpp/__init__.py
- /core/xmpp/client.py
- /bots/commands/global_remove.py
- /bots/commands/help.py
- /bots/commands/info.py
- /bots/commands/kb.py
- /bots/commands/registry.py
- /bots/commands/other.py
- /bots/commands/template.py
- /bots/commands/learn.py
- /bots/commands/stats.py
- /bots/handlers/message_handler.py
- /bots/handlers/__init__.py
- /bots/workers/__init__.py
- /bots/workers/indexing_worker.py
- /bots/xmpp/__init__.py
- /bots/xmpp/client.py
- /rag/services/qdrant_service.py
- /rag/services/giga_client.py
- /rag/services/embedding_service.py
- /rag/services/reranker_service.py
- /rag/services/__init__.py
- /rag/services/file_service.py
- /rag/services/postgres_service.py
- /rag/services/kb_service.py
- /rag/functions/check_spelling.py
- /rag/functions/__init__.py
- /rag/functions/extract_metrics.py
- /rag/functions/generate_document.py
- /rag/functions/expand_query.py
- /rag/functions/critique_answer.py
- /rag/functions/file_processor.py
- /rag/functions/check_consistency.py
- /rag/functions/summarize_document.py
- /rag/functions/rerank_context.py
- /rag/functions/intent_classify.py
- /rag/utils/__init__.py
- /rag/utils/layout_converter.py
- /rag/utils/text_utils.py
- /rag/utils/arg_parser.py
- /rag/utils/config_loader.py
- /rag/utils/logger.py
- /rag/utils/web_utils.py
2026-06-30 10:33:28 +00:00

166 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
Административные команды: !stats, !status, !clean.
- !stats статистика работы бота (сообщения, файлы, AI-запросы, ошибки, uptime).
- !status проверка состояния сервисов (GigaChat, PostgreSQL, Qdrant, диск).
- !clean очистка временной директории.
Изменения для PostgreSQL:
- Замена `conn.ping()` на `conn.execute("SELECT 1")` в команде !status.
- Обновлены тексты сообщений (MariaDB → PostgreSQL).
"""
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", "!статистика", "/статистика", "!стат", "/стат"]
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)")
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)
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить статистику")
def get_help(self) -> str:
return "Показывает статистику работы бота (админ)."
class StatusCommand(Command):
"""Проверяет состояние всех внешних сервисов (административная команда)."""
name = "!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)")
return
# --- GigaChat ---
try:
# Простой запрос для проверки доступности API
await self.bot.giga.chat([], "ping", system_prompt=None, file_id=None, temperature=0.1)
ai_status = "✅ GigaChat Online"
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)
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить статус")
def get_help(self) -> str:
return "Проверяет состояние сервисов (GigaChat, PostgreSQL, Qdrant, диск) админ."
class CleanCommand(Command):
"""Очищает временную директорию бота (temp_dir)."""
name = "!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)")
return
count = 0
temp_dir = self.bot.config.temp_dir
for f in os.listdir(temp_dir):
try:
p = os.path.join(temp_dir, f)
if os.path.isfile(p):
os.unlink(p)
elif os.path.isdir(p):
shutil.rmtree(p)
count += 1
except Exception:
pass
reply = msg.reply(f"🧹 Удалено объектов из temp_dir: {count}")
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить отчёт об очистке")
def get_help(self) -> str:
return "Очищает временную директорию бота (админ)."