Skip to content

设备监控模块 ​

「NAS 服务器」主菜单提供三类设备的完整真实监控管理:服务器、NAS、摄像头,并支持摄像头 RTSP 视频预览。严格复用项目既有的 Model + Oper(AES) + Chain/Service + Handler + guarded 路由模式,新增依赖全部纯 Go 无 CGO。

功能覆盖 ​

模块能力
服务器本机(gopsutil:CPU/内存/磁盘/网络/负载/温度/进程/运行时长)+ 远程 SSH 采集(/proc 解析)+ Agent 主动上报
NASAgent 主动上报(飞牛、绿联等国产 NAS 推荐)、群晖 Synology API、TrueNAS/FreeNAS REST API、通用 SNMP fallback(负载/内存/存储表)
摄像头ONVIF 设备发现/信息/码流地址(自写 SOAP + WS-Security)、RTSP 探活、RTSP 视频预览
告警CPU/内存/磁盘/温度阈值 + 离线告警,状态转换去重,复用通知链(bark/tg/webhook)
时序MetricSnapshot 历史快照 + 自动清理(默认保留 30 天)

后端结构 ​

internal/
├── monitor/                    设备监控包(16 文件,每文件 <400 行)
│   ├── types.go                Metrics/Thresholds/Credentials + 默认阈值
│   ├── collector.go            Collector 接口 + Registry(按 type+protocol 分发)
│   ├── host.go                 本机采集(gopsutil/v4)
│   ├── ssh.go + ssh_parse.go   远程 SSH 采集 + /proc 解析(单会话脚本,易测)
│   ├── nas.go                  NAS 分发 + JSON 宽松取值 helper
│   ├── nas_synology.go         群晖 auth.cgi/entry.cgi
│   ├── nas_truenas.go          TrueNAS /api/v2.0 + Token
│   ├── nas_snmp.go             gosnmp(hrStorage/laLoad/mem)
│   ├── camera.go + onvif.go    ONVIF SOAP 薄层 + RTSP 探活
│   ├── rtsp_probe.go           gortsplib DESCRIBE 探活
│   ├── rtsp_session.go         RTSP→WS 拉流会话(多观众复用 + annexB)
│   ├── rtsp_proxy.go           RTSPProxy(WS 鉴权/升级/读写泵/全局观众上限)
│   ├── service.go              Store 接口 + 单 ticker 扫表采集调度
│   ├── alert.go                阈值评估 + 状态转换去重
│   └── json.go                 JSON 辅助
├── db/models/models.go         +MonitorTarget / MetricSnapshot / MonitorAlert
├── db/oper/monitor.go          CRUD + AES 凭据 + Snapshot(含网络速率) + Alert 状态机
├── db/db.go                    AutoMigrate 追加三表
├── api/v1/monitor*.go          Handler(CRUD/probe/collect/metrics + alerts + stream)
├── api/router.go               /monitors + /monitor/alerts(guarded)+ /monitor/cameras/:id/stream(WS,guarded 外)
└── app/app.go                  装配 + go monSvc.Run + 每日清理 cron

采集器分发矩阵 ​

Registry 按 (type, protocol) 注册(ResolveProtocol 在 protocol 为空时按 type/host 推断):

typeprotocol采集器凭据(AES 加密)
hostlocalHostCollector(gopsutil,忽略 Host/凭据)无
hostsshSSHCollectorusername + password
host / nasagentAgentWSHub 主动上报(绕过 Collector)每设备独立 secret
naslocalHostCollector(gopsutil,支持 bind mount 磁盘路径)无
nasapiNASCollector → synology / truenasusername + password(TrueNAS 用 API Token)
nassnmpNASCollector → gosnmpusername = community
cameraonvifCameraCollector(SOAP,自动回填 RTSPURL)username + password
camerartspCameraCollector(gortsplib 探活)rtsp_url

凭据由 Oper.Credentials 解密注入 Collector,Collector 不持久化明文。

采集调度 ​

Service.Run 单 ticker(10s)扫表 → 到点(LastCheckedAt + IntervalSec ≤ now)的 target 并发采集(per-target context.WithTimeout + panic 恢复)→ RecordSnapshot(对比上次快照算网络速率)→ Alerter.Evaluate。target 增删/interval 改无需动调度(与 ws.Broadcaster.Run 同模式)。每日 3 点清理 30 天前快照。

RTSP→WebSocket 代理 ​

浏览器不能直播 RTSP。RTSPProxy 用 gortsplib 拉流 → 解 H.264 → annexB 帧 → gorilla/websocket 转发,前端 jessibuca(wasm) 解码。一路摄像头单路拉流、多观众复用(refCount + 30s 保活窗口);全局观众上限(默认 8,防资源耗尽);鉴权复用 ws.go 的 ?token=<jwt> + CheckOrigin 白名单。部署见 public/jessibuca/README.md。

API 端点 ​

方法路径说明
GET/monitors列监控目标
POST/monitors添加(TargetInput)
POST/monitors/agents创建服务器/NAS Agent(`type=host
PUT/monitors/:id更新(密码留空不改)
DELETE/monitors/:id删除(连带快照/告警)
POST/monitors/:id/probe探活
POST/monitors/:id/collect手动采集,返回当前 Metrics
GET/monitors/:id/metrics历史快照(?since=&limit=)
GET/monitor/alerts告警列表(?target_id=&unread=)
POST/monitor/alerts/:id/read标已读
GET/monitor/cameras/:id/streamRTSP→WS 视频流(?token=&url=)

告警阈值 ​

MonitorTarget.Thresholds 存 JSON,空字段回退默认:

json
{"cpu_usage":90, "mem_usage":90, "disk_usage":90, "temp":75, "offline":true}

超阈值 +10 个点以内为 warning,更高为 danger;仅「未触发→触发」时新建告警并通知(去重),「触发→恢复」时静默 Resolve。

依赖(纯 Go,无 CGO) ​

  • github.com/shirou/gopsutil/v4 — 本机系统指标(v4 是当前主线)
  • github.com/bluenviron/gortsplib/v5 — RTSP 客户端(v4 已弃用,用 v5)
  • github.com/gosnmp/gosnmp — NAS SNMP fallback
  • 已复用:golang.org/x/crypto/ssh(远程采集)、gorilla/websocket(RTSP-WS 出口)

测试 ​

go test ./internal/monitor/ 覆盖:/proc 解析、ONVIF 标签提取、阈值解析、Registry 分发、本机采集烟雾、告警状态转换去重、离线告警。RTSP 代理/真实设备采集因需硬件不在单测范围。