2026-02-06 16:22:10 +08:00
|
|
|
from time import sleep
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
import random
|
2025-12-08 16:20:22 +08:00
|
|
|
|
2026-02-06 16:22:10 +08:00
|
|
|
from rich.console import Console
|
|
|
|
|
from rich.panel import Panel
|
|
|
|
|
from rich.table import Table
|
|
|
|
|
from rich.layout import Layout
|
|
|
|
|
from rich.align import Align
|
|
|
|
|
from rich.text import Text
|
|
|
|
|
from rich.live import Live
|
|
|
|
|
|
|
|
|
|
console = Console()
|
|
|
|
|
|
|
|
|
|
def make_header() -> Panel:
|
|
|
|
|
title = Text("SYSTEM DASHBOARD", style="bold cyan")
|
|
|
|
|
subtitle = Text(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), style="dim")
|
|
|
|
|
return Panel(Align.center(title + "\n" + subtitle), border_style="cyan")
|
|
|
|
|
|
|
|
|
|
def make_metrics_table(cpu: int, mem: int, qps: int) -> Panel:
|
|
|
|
|
t = Table(show_header=True, header_style="bold magenta", expand=True)
|
|
|
|
|
t.add_column("Metric")
|
|
|
|
|
t.add_column("Value", justify="right")
|
|
|
|
|
t.add_row("CPU", f"{cpu}%")
|
|
|
|
|
t.add_row("Memory", f"{mem}%")
|
|
|
|
|
t.add_row("QPS", str(qps))
|
|
|
|
|
return Panel(t, title="Metrics", border_style="magenta")
|
|
|
|
|
|
|
|
|
|
def make_status_panel(status: str, logs: list[str]) -> Panel:
|
|
|
|
|
body = "\n".join(logs[-8:]) if logs else "No logs yet."
|
|
|
|
|
text = Text(f"[bold]Status:[/bold] {status}\n\n", style="white")
|
|
|
|
|
text.append(body, style="dim")
|
|
|
|
|
return Panel(text, title="Status / Logs", border_style="green")
|
|
|
|
|
|
|
|
|
|
def make_footer(msg: str) -> Panel:
|
|
|
|
|
return Panel(Text(msg, style="bold yellow"), border_style="yellow")
|
|
|
|
|
|
|
|
|
|
def build_layout(cpu: int, mem: int, qps: int, status: str, logs: list[str]) -> Layout:
|
|
|
|
|
layout = Layout()
|
|
|
|
|
layout.split_column(
|
|
|
|
|
Layout(make_header(), name="header", size=5),
|
|
|
|
|
Layout(name="body", ratio=1),
|
|
|
|
|
Layout(make_footer("Press Ctrl+C to exit"), name="footer", size=3),
|
|
|
|
|
)
|
|
|
|
|
layout["body"].split_row(
|
|
|
|
|
Layout(make_metrics_table(cpu, mem, qps), name="left", ratio=1),
|
|
|
|
|
Layout(make_status_panel(status, logs), name="right", ratio=2),
|
|
|
|
|
)
|
|
|
|
|
return layout
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
logs = []
|
|
|
|
|
status = "OK"
|
|
|
|
|
with Live(console=console, refresh_per_second=8, screen=True):
|
|
|
|
|
while True:
|
|
|
|
|
cpu = random.randint(1, 100)
|
|
|
|
|
mem = random.randint(1, 100)
|
|
|
|
|
qps = random.randint(50, 5000)
|
|
|
|
|
|
|
|
|
|
if cpu > 85 or mem > 90:
|
|
|
|
|
status = "WARN"
|
|
|
|
|
logs.append(f"{datetime.now().strftime('%H:%M:%S')} - High load detected")
|
|
|
|
|
else:
|
|
|
|
|
status = "OK"
|
|
|
|
|
if random.random() < 0.2:
|
|
|
|
|
logs.append(f"{datetime.now().strftime('%H:%M:%S')} - Heartbeat")
|
|
|
|
|
|
|
|
|
|
layout = build_layout(cpu, mem, qps, status, logs)
|
|
|
|
|
Live.get_renderable = lambda self: layout # 小技巧:避免重复创建 Live
|
|
|
|
|
sleep(0.15)
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
try:
|
|
|
|
|
main()
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
console.print("\nBye!", style="bold red")
|