Add alert tools, mutes, short status, and backup summary
This commit is contained in:
95
handlers/alerts_admin.py
Normal file
95
handlers/alerts_admin.py
Normal file
@@ -0,0 +1,95 @@
|
||||
import time
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from aiogram import F
|
||||
from aiogram.types import Message
|
||||
from app import dp, bot, cfg, ADMIN_ID
|
||||
from auth import is_admin_msg
|
||||
from services.alert_mute import set_mute, clear_mute, list_mutes
|
||||
from services.incidents import read_recent
|
||||
from services.notify import notify
|
||||
|
||||
|
||||
HELP_TEXT = (
|
||||
"Alerts:\n"
|
||||
"/alerts test <critical|warn|info> - send test alert\n"
|
||||
"/alerts mute <category> <minutes> - mute alerts for category\n"
|
||||
"/alerts unmute <category> - unmute category\n"
|
||||
"/alerts list - show active mutes\n"
|
||||
"/alerts recent [hours] - show incidents log (default 24h)\n"
|
||||
"Categories: load, disk, smart, ssl, docker, test\n"
|
||||
)
|
||||
|
||||
|
||||
@dp.message(F.text.startswith("/alerts"))
|
||||
async def alerts_cmd(msg: Message):
|
||||
if not is_admin_msg(msg):
|
||||
return
|
||||
|
||||
parts = msg.text.split()
|
||||
if len(parts) < 2:
|
||||
await msg.answer(HELP_TEXT)
|
||||
return
|
||||
|
||||
action = parts[1].lower()
|
||||
|
||||
if action == "test":
|
||||
level = parts[2].lower() if len(parts) >= 3 else "info"
|
||||
if level not in ("critical", "warn", "info"):
|
||||
level = "info"
|
||||
key = f"test:{level}:{int(time.time())}"
|
||||
await notify(bot, msg.chat.id, f"[TEST] {level.upper()} alert", level=level, key=key, category="test")
|
||||
await msg.answer(f"Sent test alert: {level}")
|
||||
return
|
||||
|
||||
if action == "mute":
|
||||
if len(parts) < 3:
|
||||
await msg.answer("Usage: /alerts mute <category> <minutes>")
|
||||
return
|
||||
category = parts[2].lower()
|
||||
minutes = 60
|
||||
if len(parts) >= 4:
|
||||
try:
|
||||
minutes = max(1, int(parts[3]))
|
||||
except ValueError:
|
||||
minutes = 60
|
||||
until = set_mute(category, minutes * 60)
|
||||
dt = datetime.fromtimestamp(until, tz=timezone.utc).astimezone()
|
||||
await msg.answer(f"🔕 Muted {category} for {minutes}m (until {dt:%Y-%m-%d %H:%M:%S})")
|
||||
return
|
||||
|
||||
if action == "unmute":
|
||||
if len(parts) < 3:
|
||||
await msg.answer("Usage: /alerts unmute <category>")
|
||||
return
|
||||
category = parts[2].lower()
|
||||
clear_mute(category)
|
||||
await msg.answer(f"🔔 Unmuted {category}")
|
||||
return
|
||||
|
||||
if action in ("list", "mutes"):
|
||||
mutes = list_mutes()
|
||||
if not mutes:
|
||||
await msg.answer("🔔 No active mutes")
|
||||
return
|
||||
lines = ["🔕 Active mutes:"]
|
||||
for cat, secs in mutes.items():
|
||||
mins = max(0, secs) // 60
|
||||
lines.append(f"- {cat}: {mins}m left")
|
||||
await msg.answer("\n".join(lines))
|
||||
return
|
||||
|
||||
if action == "recent":
|
||||
hours = 24
|
||||
if len(parts) >= 3:
|
||||
try:
|
||||
hours = max(1, int(parts[2]))
|
||||
except ValueError:
|
||||
hours = 24
|
||||
rows = read_recent(cfg, hours, limit=50)
|
||||
if not rows:
|
||||
await msg.answer(f"No incidents in last {hours}h")
|
||||
return
|
||||
await msg.answer("🧾 Incidents:\n" + "\n".join(rows))
|
||||
return
|
||||
|
||||
await msg.answer(HELP_TEXT)
|
||||
Reference in New Issue
Block a user