Add weekly report, multi-admin, docker health cmd, backup tail, openwrt filters
This commit is contained in:
@@ -4,8 +4,10 @@ from app import dp
|
||||
from auth import is_admin_msg
|
||||
from keyboards import docker_kb, docker_inline_kb
|
||||
from services.docker import container_uptime, docker_cmd
|
||||
from services.incidents import log_incident
|
||||
from state import DOCKER_MAP, LOG_FILTER_PENDING
|
||||
import time
|
||||
import json
|
||||
|
||||
|
||||
async def cmd_docker_status(msg: Message):
|
||||
@@ -42,6 +44,7 @@ async def cmd_docker_status(msg: Message):
|
||||
lines.append(f"{icon} {alias}: {status} ({up})")
|
||||
|
||||
await msg.answer("\n".join(lines), reply_markup=docker_kb)
|
||||
log_incident(cfg, f"docker_status by {msg.from_user.id}")
|
||||
|
||||
except Exception as e:
|
||||
# ⬅️ КРИТИЧЕСКИ ВАЖНО
|
||||
@@ -83,6 +86,45 @@ async def ds_cmd(msg: Message):
|
||||
await cmd_docker_status(msg)
|
||||
|
||||
|
||||
@dp.message(F.text.startswith("/docker_health"))
|
||||
async def docker_health(msg: Message):
|
||||
if not is_admin_msg(msg):
|
||||
return
|
||||
parts = msg.text.split()
|
||||
if len(parts) < 2:
|
||||
await msg.answer("Usage: /docker_health <alias>")
|
||||
return
|
||||
alias = parts[1]
|
||||
real = DOCKER_MAP.get(alias)
|
||||
if not real:
|
||||
await msg.answer(f"⚠️ Unknown container: {alias}", reply_markup=docker_kb)
|
||||
return
|
||||
rc, out = await docker_cmd(["inspect", "-f", "{{json .State.Health}}", real], timeout=10)
|
||||
if rc != 0 or not out.strip():
|
||||
await msg.answer(f"⚠️ Failed to get health for {alias}", reply_markup=docker_kb)
|
||||
return
|
||||
try:
|
||||
data = json.loads(out)
|
||||
except json.JSONDecodeError:
|
||||
await msg.answer(f"⚠️ Invalid health JSON for {alias}", reply_markup=docker_kb)
|
||||
return
|
||||
status = data.get("Status", "n/a")
|
||||
fail = data.get("FailingStreak", "n/a")
|
||||
logs = data.get("Log") or []
|
||||
lines = [f"🐳 {alias} health", f"Status: {status}", f"Failing streak: {fail}"]
|
||||
if logs:
|
||||
lines.append("Recent logs:")
|
||||
for entry in logs[-5:]:
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
ts = entry.get("Start") or entry.get("End") or ""
|
||||
exitc = entry.get("ExitCode", "")
|
||||
out_line = entry.get("Output", "").strip()
|
||||
lines.append(f"- {ts} rc={exitc} {out_line}")
|
||||
await msg.answer("\n".join(lines), reply_markup=docker_kb)
|
||||
log_incident(cfg, f"docker_health alias={alias} by {msg.from_user.id}")
|
||||
|
||||
|
||||
@dp.message(F.text == "📈 Stats")
|
||||
async def dstats(msg: Message):
|
||||
if not is_admin_msg(msg):
|
||||
|
||||
Reference in New Issue
Block a user