229 lines
8.8 KiB
Markdown
229 lines
8.8 KiB
Markdown
# Server Monitor
|
||
|
||
Linux 服务器监控展示牌。监听 `0.0.0.0`,通过 `/proc`、`/sys` 和 `statvfs` 采集系统指标,在 **1024×768** 优化的面板上自动滚动展示,并随屏幕尺寸等比缩放。
|
||
|
||

|
||
|
||
## 特性
|
||
|
||
- **零第三方依赖**:只需要 Python 3.8+,不需要 pip 安装任何包。
|
||
- **完整指标**:CPU 使用率 / 每核心 / user-system-iowait-steal 拆分、内存与 Swap、LOAD 1/5/15、Uptime、文件系统、磁盘 I/O、网络速率与累计流量、Top 进程、温度、频率。
|
||
- **展示牌设计**:1024×768 基准,5 个页面自动轮播;顶部固定主机名、当前时间、时区、Uptime、IP;底部状态跑马灯。
|
||
- **实时数据**:默认每秒采样一次;SSE 推送,断线后自动回退到 HTTP 轮询。
|
||
- **无需前端构建**:原生 HTML/CSS/Canvas,无 CDN、无外网字体或图标,内网离线可用。
|
||
- **可选 Basic 认证**;systemd 服务使用 `DynamicUser` 降权运行,只读访问系统数据。
|
||
- **内置演示模式**:在没有 Linux `/proc` 的机器上也能预览完整面板。
|
||
|
||
## 面板
|
||
|
||
| 页面 | 内容 |
|
||
| --- | --- |
|
||
| 01 系统概览 | CPU / 内存 / LOAD / 文件系统 / 网络速率,节点信息 |
|
||
| 02 处理器与负载 | 大环图、16 核心网格、CPU 拆分、CPU Top 进程、负载趋势 |
|
||
| 03 内存 | 内存构成、Swap、60 秒趋势、内存 Top 进程 |
|
||
| 04 存储 | 文件系统用量汇总、块设备 I/O、I/O 60 秒趋势 |
|
||
| 05 网络 | 总吞吐、RX/TX 趋势、每网卡速率/累计/错误/链路速率 |
|
||
|
||
默认每页轮播 10 秒;任意页面都会保留主机名、服务器时间、时区和 Uptime。底部的 STATUS 跑马灯会滚动显示阈值告警与实时摘要。
|
||
|
||
## 快速开始
|
||
|
||
### Linux(实时模式)
|
||
|
||
```bash
|
||
# 需要 Python 3.8+
|
||
python3 monitor.py --bind 0.0.0.0 --port 8787
|
||
```
|
||
|
||
浏览器打开 `http://<服务器IP>:8787/`。
|
||
|
||
### 任意系统(演示模式)
|
||
|
||
```bash
|
||
python3 monitor.py --demo --bind 127.0.0.1 --port 8787
|
||
```
|
||
|
||
演示模式不读取本机 `/proc`,使用模拟的 16 核服务器数据,适合做 UI 预览、截图和无 Linux 环境下的开发。
|
||
|
||
### 一次性输出 JSON
|
||
|
||
```bash
|
||
python3 monitor.py --once --demo
|
||
python3 monitor.py --once # Linux 上采样两次后输出实时快照
|
||
```
|
||
|
||
## 安装为 systemd 服务
|
||
|
||
```bash
|
||
chmod +x install.sh
|
||
sudo ./install.sh
|
||
```
|
||
|
||
脚本会把程序安装到 `/opt/server-monitor`,安装 `server-monitor.service`,并立即启动。默认监听 `0.0.0.0:8787`。如果仓库本身已经放在 `/opt/server-monitor`,脚本会跳过自我复制,可直接重复运行。
|
||
|
||
```bash
|
||
systemctl status server-monitor --no-pager
|
||
journalctl -u server-monitor -f
|
||
```
|
||
|
||
如需启用 Basic 认证:
|
||
|
||
```bash
|
||
sudo vi /etc/server-monitor.env
|
||
# 写入:
|
||
# SERVER_MONITOR_AUTH=admin:换成一个强密码
|
||
sudo systemctl restart server-monitor
|
||
```
|
||
|
||
密码中不能包含换行;用户名和密码用第一个冒号分隔,密码本身可以包含冒号。修改端口推荐使用 systemd drop-in:
|
||
|
||
```bash
|
||
sudo systemctl edit server-monitor
|
||
```
|
||
|
||
```ini
|
||
[Service]
|
||
ExecStart=
|
||
ExecStart=/usr/bin/python3 /opt/server-monitor/monitor.py --bind 0.0.0.0 --port 9000
|
||
```
|
||
|
||
然后执行 `sudo systemctl daemon-reload && sudo systemctl restart server-monitor`。
|
||
|
||
## 命令行参数
|
||
|
||
| 参数 | 默认值 | 说明 |
|
||
| --- | --- | --- |
|
||
| `--bind` | `0.0.0.0` | 监听地址。只给本机看可用 `127.0.0.1` |
|
||
| `--port` | `8787` | 监听端口 |
|
||
| `--interval` | `1.0` | 采样间隔(秒,最小 0.2) |
|
||
| `--demo` | 关闭 | 使用演示数据,可在 Windows/macOS 运行 |
|
||
| `--once` | 关闭 | 输出一次 JSON 快照后退出 |
|
||
| `--auth USER:PASSWORD` | 无 | 启用 HTTP Basic 认证 |
|
||
| `--web-dir DIR` | 内置 `web/` | 前端静态文件目录 |
|
||
| `--verbose` | 关闭 | 输出 HTTP 访问日志 |
|
||
| `--version` | — | 显示版本 |
|
||
|
||
环境变量 `SERVER_MONITOR_AUTH` 等价于 `--auth`,systemd 安装方式使用该变量。
|
||
|
||
## URL 参数与快捷键
|
||
|
||
| 参数 | 示例 | 说明 |
|
||
| --- | --- | --- |
|
||
| `page` | `?page=3` | 初始显示第 1–5 页 |
|
||
| `rotate` | `?rotate=15` | 每页停留秒数(4–120,默认 10) |
|
||
| `paused` | `?paused=1` | 打开时暂停自动轮播 |
|
||
|
||
快捷键:
|
||
|
||
- `Space`:暂停 / 继续轮播
|
||
- `←` / `→`:上一页 / 下一页
|
||
- `1`–`5`:直接跳转页面
|
||
- `F`:全屏
|
||
|
||
适合做值守大屏或 kiosk。页面会按 `min(视口宽/1024, 视口高/768)` 等比缩放,4:3 屏幕刚好铺满,16:9 屏幕居中留边且不会拉伸。
|
||
|
||
## HTTP 接口
|
||
|
||
| 路径 | 说明 |
|
||
| --- | --- |
|
||
| `/` | 展示牌 |
|
||
| `/api/snapshot` | 当前完整 JSON 快照(含 60 点历史) |
|
||
| `/api/stream` | SSE 实时推送,每个采样点一条 `data:` |
|
||
| `/healthz` | 健康检查,返回 `{ok, samples, interval, uptime_seconds}` |
|
||
|
||
`/healthz` 不要求认证;其余路径在配置认证后需要 Basic 凭据。接口只读,不接受任何写入或控制指令。
|
||
|
||
## 指标来源
|
||
|
||
| 指标 | 来源 |
|
||
| --- | --- |
|
||
| CPU 总量 / 每核心 / 拆分 | `/proc/stat` |
|
||
| CPU 型号 / 物理核心 | `/proc/cpuinfo` |
|
||
| CPU 频率 | `cpufreq/scaling_cur_freq`,回退 `/proc/cpuinfo` |
|
||
| CPU 温度 | `/sys/class/thermal/thermal_zone*`,回退 `hwmon` |
|
||
| 内存 / Swap | `/proc/meminfo` |
|
||
| LOAD / 运行线程 | `/proc/loadavg` |
|
||
| Uptime / 启动时间 | `/proc/uptime` |
|
||
| 文件系统 | `/proc/mounts` + `statvfs(2)` |
|
||
| 磁盘 I/O | `/proc/diskstats` + `/sys/class/block`(过滤分区) |
|
||
| 网络速率 / 累计 | `/proc/net/dev` |
|
||
| 网卡 IP / 默认路由 | `ip -j addr`(可选)、`/proc/net/route`、UDP 路由探测 |
|
||
| 网卡链路速率 | `/sys/class/net/<iface>/speed` |
|
||
| Top 进程 | `/proc/<pid>/stat`、`/proc/<pid>/cmdline` |
|
||
| 主机信息 | `/etc/os-release`、`uname(2)`、`gethostname(2)` |
|
||
|
||
说明:
|
||
|
||
- 网络汇总默认排除 `lo`、veth、docker、br-、virbr、cni 等虚拟接口,避免容器主机重复计数;网卡明细仍会列出主要接口。
|
||
- 磁盘 I/O 已过滤分区设备,避免整盘和分区重复统计;容器内的 `overlay` 根文件系统会按实际挂载显示。
|
||
- 进程 CPU 百分比是按“全部逻辑核心”归一化的,可超过 100%(例如 4 核机器上单进程跑满 4 核约等于 400%)。
|
||
- 所有采样都在一个后台线程完成,多个浏览器同时打开也只产生一份系统采样。
|
||
|
||
## 安全与部署建议
|
||
|
||
- 默认监听所有网卡,但**无认证**。部署到公网前请启用 `SERVER_MONITOR_AUTH`,并用防火墙限制来源,或放在带 TLS 的反向代理后面。
|
||
- 程序以只读方式访问 `/proc`、`/sys` 和挂载点;systemd 单元使用 `DynamicUser=yes`、`ProtectSystem=strict`、空 capability 集。
|
||
- 如果服务器使用了 `hidepid=2`,普通用户可能看不到其他用户的进程,进程 Top 会相应减少;这是内核权限策略,不是面板故障。
|
||
- 如果把 `/home` 下的挂载点也纳入监控,请确认 systemd 的 `ProtectHome=read-only` 不会改变你的预期;可按需删除该行。
|
||
- Basic 认证只保护凭据传输前的内容,公网使用务必加 HTTPS。
|
||
|
||
## 开发与测试
|
||
|
||
```bash
|
||
python3 -m unittest discover -s tests -v
|
||
node --check web/app.js
|
||
```
|
||
|
||
测试使用临时伪造的 `/proc` 数据验证 CPU 差值、内存、网络速率、磁盘 I/O 和演示快照,不会读取或修改真实服务器数据。
|
||
|
||
目录结构:
|
||
|
||
```text
|
||
monitor.py CLI 入口
|
||
servermon/metrics.py /proc /sys 解析与快照
|
||
servermon/demo.py 演示数据源
|
||
servermon/service.py 后台采样、历史环形缓冲、SSE 广播
|
||
servermon/web.py HTTP / SSE / 静态文件 / Basic Auth
|
||
web/ 原生前端(HTML/CSS/Canvas)
|
||
deploy/server-monitor.service
|
||
install.sh
|
||
tests/test_metrics.py
|
||
```
|
||
|
||
## 卸载
|
||
|
||
```bash
|
||
sudo systemctl disable --now server-monitor
|
||
sudo rm -f /etc/systemd/system/server-monitor.service
|
||
sudo systemctl daemon-reload
|
||
sudo rm -rf /opt/server-monitor
|
||
sudo rm -f /etc/server-monitor.env
|
||
```
|
||
|
||
## 故障排查
|
||
|
||
**页面一直显示“连接中”或空白**
|
||
|
||
- 确认访问的是 `http://IP:8787/`,且防火墙放行端口。
|
||
- 查看 `journalctl -u server-monitor -f`。
|
||
- 非 Linux 上启动实时模式会直接报错,请加 `--demo` 或把程序部署到 Linux。
|
||
|
||
**中文显示成方框**
|
||
|
||
目标浏览器缺少中文字体。Debian/Ubuntu 可安装 `fonts-noto-cjk`,或在浏览器端使用包含中文字体的系统。
|
||
|
||
**磁盘列表为空**
|
||
|
||
检查挂载的文件系统类型是否在 `REAL_FS_TYPES` 中;容器内的特殊文件系统可能被有意过滤。可以先用 `findmnt` 确认挂载类型。
|
||
|
||
**进程 Top 为空**
|
||
|
||
检查 `/proc` 是否被 `hidepid` 限制,以及 systemd 的 `DynamicUser` 是否有权限读取目标进程的 `stat`。
|
||
|
||
**端口被占用**
|
||
|
||
```bash
|
||
ss -lntp | grep 8787
|
||
```
|
||
|
||
改用 `--port` 或 systemd drop-in 修改端口。 |