website patch
This commit is contained in:
1 parent
b1ff45794a
commit
4fa7d5ca50
2 files changed
+34
-12
No files matched your search
@@ -32,4 +32,4 @@ async def setup(bot: commands.Bot) -> None:
|
|||||||
async def teardown(bot: commands.Bot) -> None:
|
async def teardown(bot: commands.Bot) -> None:
|
||||||
global _sync
|
global _sync
|
||||||
if _sync is not None:
|
if _sync is not None:
|
||||||
_sync.stop()
|
await _sync.stop()
|
||||||
@@ -6,6 +6,7 @@ import re
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
import psutil
|
import psutil
|
||||||
|
from google.cloud import firestore
|
||||||
|
|
||||||
from .config import get_db, SYSINFO_INTERVAL
|
from .config import get_db, SYSINFO_INTERVAL
|
||||||
|
|
||||||
@@ -13,6 +14,8 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
FASTFETCH_CACHE_SECS = 300 # refresh fastfetch every 5 minutes
|
FASTFETCH_CACHE_SECS = 300 # refresh fastfetch every 5 minutes
|
||||||
|
|
||||||
|
VIRTUAL_NIC_PREFIXES = ("lo", "docker", "br-", "veth", "tailscale", "tun", "wg", "virbr")
|
||||||
|
|
||||||
|
|
||||||
def _fmt_size(b: int) -> str:
|
def _fmt_size(b: int) -> str:
|
||||||
"""Bytes → human-readable string (auto-scales B → TB)."""
|
"""Bytes → human-readable string (auto-scales B → TB)."""
|
||||||
@@ -23,6 +26,13 @@ def _fmt_size(b: int) -> str:
|
|||||||
return f"{b:.1f} PB"
|
return f"{b:.1f} PB"
|
||||||
|
|
||||||
|
|
||||||
|
def _fmt_duration(seconds: int) -> str:
|
||||||
|
days, r = divmod(seconds, 86400)
|
||||||
|
hours, r = divmod(r, 3600)
|
||||||
|
minutes, _ = divmod(r, 60)
|
||||||
|
return f"{days}d {hours}h {minutes}m" if days else f"{hours}h {minutes}m"
|
||||||
|
|
||||||
|
|
||||||
class SysInfoSync:
|
class SysInfoSync:
|
||||||
"""Background task: collect system stats and push to Firestore."""
|
"""Background task: collect system stats and push to Firestore."""
|
||||||
|
|
||||||
@@ -39,12 +49,19 @@ class SysInfoSync:
|
|||||||
self._task = asyncio.create_task(self._run())
|
self._task = asyncio.create_task(self._run())
|
||||||
log.info("SysInfo → Firestore sync started (every %ds)", SYSINFO_INTERVAL)
|
log.info("SysInfo → Firestore sync started (every %ds)", SYSINFO_INTERVAL)
|
||||||
|
|
||||||
def stop(self) -> None:
|
async def stop(self) -> None:
|
||||||
if self._task is None:
|
if self._task is None:
|
||||||
return
|
return
|
||||||
self._task.cancel()
|
self._task.cancel()
|
||||||
self._task = None
|
self._task = None
|
||||||
log.info("SysInfo → Firestore sync stopped")
|
log.info("SysInfo → Firestore sync stopped")
|
||||||
|
# Clean shutdown → flip the website dot to offline. Crashes can't do
|
||||||
|
# this; the website also treats a stale `updatedAt` as offline.
|
||||||
|
try:
|
||||||
|
await get_db().collection("sysinfo").document("server").set(
|
||||||
|
{"online": False, "updatedAt": firestore.SERVER_TIMESTAMP}, merge=True)
|
||||||
|
except Exception:
|
||||||
|
log.warning("Could not mark sysinfo offline", exc_info=True)
|
||||||
|
|
||||||
# ── loop ────────────────────────────────────────────────────────────
|
# ── loop ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -77,12 +94,15 @@ class SysInfoSync:
|
|||||||
"swapUsed": stats["swap_used"],
|
"swapUsed": stats["swap_used"],
|
||||||
"swapTotal": stats["swap_total"],
|
"swapTotal": stats["swap_total"],
|
||||||
"uptime": stats["uptime"],
|
"uptime": stats["uptime"],
|
||||||
|
"botUptime": stats["bot_uptime"],
|
||||||
|
"processes": stats["processes"],
|
||||||
"load1": stats["load1"],
|
"load1": stats["load1"],
|
||||||
"load5": stats["load5"],
|
"load5": stats["load5"],
|
||||||
"load15": stats["load15"],
|
"load15": stats["load15"],
|
||||||
"netSent": stats["net_sent"],
|
"netSent": stats["net_sent"],
|
||||||
"netRecv": stats["net_recv"],
|
"netRecv": stats["net_recv"],
|
||||||
"fetch": fetch,
|
"fetch": fetch,
|
||||||
|
"updatedAt": firestore.SERVER_TIMESTAMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
@@ -97,13 +117,13 @@ class SysInfoSync:
|
|||||||
disk = psutil.disk_usage("/")
|
disk = psutil.disk_usage("/")
|
||||||
swap = psutil.swap_memory()
|
swap = psutil.swap_memory()
|
||||||
load1, load5, load15 = psutil.getloadavg()
|
load1, load5, load15 = psutil.getloadavg()
|
||||||
net = psutil.net_io_counters()
|
nics = psutil.net_io_counters(pernic=True)
|
||||||
uptime_seconds = int(time.time() - psutil.boot_time())
|
physical = [c for name, c in nics.items() if not name.startswith(VIRTUAL_NIC_PREFIXES)]
|
||||||
|
net_sent = sum(c.bytes_sent for c in physical)
|
||||||
days, r = divmod(uptime_seconds, 86400)
|
net_recv = sum(c.bytes_recv for c in physical)
|
||||||
hours, r = divmod(r, 3600)
|
now = time.time()
|
||||||
minutes, _ = divmod(r, 60)
|
uptime_seconds = int(now - psutil.boot_time())
|
||||||
uptime_str = f"{days}d {hours}h {minutes}m" if days else f"{hours}h {minutes}m"
|
bot_uptime_seconds = int(now - psutil.Process().create_time())
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"cpu": round(cpu, 1),
|
"cpu": round(cpu, 1),
|
||||||
@@ -116,12 +136,14 @@ class SysInfoSync:
|
|||||||
"swap": round(swap.percent, 1),
|
"swap": round(swap.percent, 1),
|
||||||
"swap_used": _fmt_size(swap.used),
|
"swap_used": _fmt_size(swap.used),
|
||||||
"swap_total": _fmt_size(swap.total),
|
"swap_total": _fmt_size(swap.total),
|
||||||
"uptime": uptime_str,
|
"uptime": _fmt_duration(uptime_seconds),
|
||||||
|
"bot_uptime": _fmt_duration(bot_uptime_seconds),
|
||||||
|
"processes": len(psutil.pids()),
|
||||||
"load1": round(load1, 1),
|
"load1": round(load1, 1),
|
||||||
"load5": round(load5, 1),
|
"load5": round(load5, 1),
|
||||||
"load15": round(load15, 1),
|
"load15": round(load15, 1),
|
||||||
"net_sent": _fmt_size(net.bytes_sent),
|
"net_sent": _fmt_size(net_sent),
|
||||||
"net_recv": _fmt_size(net.bytes_recv),
|
"net_recv": _fmt_size(net_recv),
|
||||||
}
|
}
|
||||||
|
|
||||||
async def _get_fastfetch(self) -> str:
|
async def _get_fastfetch(self) -> str:
|
||||||
|
|||||||
Reference in new issue
Block a user