LinuxAwesomeBot: OneBot 11 Linux monitoring bot (power/CPU/temp/alerts)

This commit is contained in:
snowy-yang committed 2026-09-12 14:20:47 +08:00
commit b1ffd86bd9
12 files changed
+1468

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
"""后台高负载告警任务。"""
import asyncio
import logging
import time
import monitor
log = logging.getLogger("alerter")
class Alerter:
def __init__(self, ob, cfg: dict):
self.ob = ob
self.cfg = cfg
self.interval = cfg.get("interval", 10)
self.threshold = cfg.get("cpu_threshold", 85.0)
self.consecutive_need = cfg.get("consecutive", 2)
self.cooldown = cfg.get("cooldown", 600)
self.top_n = cfg.get("top_n", 5)
self.groups = cfg.get("groups", []) or []
self.friends = cfg.get("friends", []) or []
self._consecutive = 0
self._alerting = False # 当前是否处于高负载状态
self._last_alert_ts = 0.0
self._task = None
def start(self):
self._task = asyncio.get_running_loop().create_task(self._loop())
async def stop(self):
if self._task:
self._task.cancel()
async def _loop(self):
log.info("告警监控已启动: 阈值 %.0f%%, 连续 %d 次, 间隔 %ds, 冷却 %ds",
self.threshold, self.consecutive_need, self.interval, self.cooldown)
while True:
try:
await asyncio.sleep(self.interval)
if not self.ob.connected or (not self.groups and not self.friends):
continue
cpu = monitor.get_cpu()
await self._check(cpu["percent"])
except asyncio.CancelledError:
break
except Exception:
log.exception("告警循环出错")
async def _check(self, cpu_percent: float):
now = time.monotonic()
if cpu_percent >= self.threshold:
self._consecutive += 1
if (self._consecutive >= self.consecutive_need
and (not self._alerting or now - self._last_alert_ts >= self.cooldown)):
self._alerting = True
self._last_alert_ts = now
await self._send_alert(cpu_percent)
else:
self._consecutive = 0
if self._alerting:
self._alerting = False
msg = (f"✅ [恢复] 服务器 CPU 已回落到 {cpu_percent:.1f}%,"
f"负载恢复正常。")
log.info(msg)
await self.ob.broadcast(msg, self.groups, self.friends)
async def _send_alert(self, cpu_percent: float):
top = monitor.get_top_processes(self.top_n)
cpu = monitor.get_cpu()
load = cpu["load"]
lines = [
f"⚠️ [高负载告警] CPU 持续超过 {self.threshold:.0f}%,当前 {cpu_percent:.1f}%",
f"负载: {load[0]:.2f} / {load[1]:.2f} / {load[2]:.2f} 核心: {cpu['cores']}",
"",
f"TOP{self.top_n} 高负载进程:",
]
for i, p in enumerate(top, 1):
lines.append(
f"{i}. {p['name']} (PID {p['pid']}) CPU {p['cpu']}% 内存 {p['mem_mb']}MB"
)
msg = "\n".join(lines)
log.warning("触发高负载告警: %.1f%%", cpu_percent)
await self.ob.broadcast(msg, self.groups, self.friends)