Files
mfd-monitor-agent/plan.md
codex 89d5e27874 💥 feat(agent)!: 添加主机监控代理首版
* 实现周期采集、快照缓存、本地 HTTP API 和主动上报

* 补齐 Linux 和 Windows 主机、网络、资源、进程和 TCP 采集

* 添加服务生命周期管理、配置加载、构建脚本和测试覆盖

BREAKING CHANGE: network.ips 拆分为 network.ipv4s 和 network.ipv6s。
2026-05-18 15:25:51 +00:00

350 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

高权限主机状态 Agent 设计方案
1. 项目简介
MFD Monitor Agent 是一个使用 Go 实现的单二进制主机状态监控 agent,用于在 Windows 和 Linux 主机上采集并暴露完整主机状态。
agent 提供本地 HTTP API,默认监听 127.0.0.1:8080。GET /health 用于返回进程存活状态和最近一次快照元数据;GET /status 用于返回缓存中的完整主机状态快照。
agent 通过后台周期采集刷新内存缓存,避免每次 HTTP 请求都实时扫描系统,从而提升响应速度并降低系统负载。
agent 支持可选的周期性 HTTP POST 主动上报,上报数据直接复用 HostStatus JSON 结构,避免维护两套数据模型。
agent 支持通过 CLI 管理服务生命周期,包括 run、install、uninstall、start、stop 和 version。Linux 侧面向 systemd service,Windows 侧面向 Windows Service。
2. 目标
开发一个独立的 Go 单二进制 agent,支持安装为 Windows Service 和 Linux systemd service。
安装阶段要求管理员/root;首版运行阶段也默认使用高权限账户,以稳定采集完整主机信息。
agent 对外提供 HTTP 接口,核心接口为 GET /status,单次返回完整主机状态快照,包含:
- IP
- MAC
- 主机名
- CPU
- 内存
- 磁盘
- 完整进程列表
- 监听中的 TCP 端口及其进程映射
同时 agent 支持按周期向中心端固定 HTTP 接口主动上报同一份状态 JSON。
3. 服务权限说明
注册为服务这一步基本都需要管理员权限:
- Windows:创建、删除、启动、停止 Windows Service 需要管理员权限
- Linux:写入 systemd unit、systemctl enable/start 通常需要 root
服务运行阶段:
- 如果只读取主机名、IP、MAC、内存、磁盘、CPU,通常不一定需要管理员权限
- 但如果要稳定获取完整进程列表,以及监听 TCP 端口和进程映射,建议服务默认也以高权限运行
建议首版权限策略:
- 安装阶段:必须管理员/root
- 运行阶段:默认高权限运行
- 接口层:即使某些字段采集失败,也不要让整个 /status 失败,应返回 partial 或错误原因
4. 架构方案
推荐使用“单进程一体化”架构。
一个 agent 进程中同时承担以下职责:
- 周期采集主机状态
- 缓存最近一次状态
- 对外提供 HTTP 查询接口
- 定时向中心端主动上报状态
- 负责 Windows/Linux 服务生命周期管理
虽然是单进程,但代码建议按模块拆分:
- collector/system:主机名、OS、架构、启动时间、采集时间
- collector/network:网卡、IPv4/IPv6、MAC
- collector/resource:CPU、内存、磁盘
- collector/process:完整进程列表
- collector/socket:TCP 监听端口及其进程映射
- snapshot:聚合各采集器输出,形成统一 HostStatus
- httpapi:提供 GET /health、GET /status
- reporter:定时 POST HostStatus 到中心端
- service:封装 Windows/Linux 服务生命周期和安装命令
- config:统一加载监听地址、采集周期、上报周期、上报目标、机器标识等配置
5. HTTP 接口设计
建议保留两个接口:
- GET /health
用于返回进程存活、版本、最近快照时间、最近采集状态
- GET /status
返回完整 HostStatus
根据当前确认的需求,/status 采用单接口全量返回,不拆分接口,不使用 include 参数。
默认监听地址建议为:
- 127.0.0.1
如果后续需要局域网访问,再通过配置改为指定内网地址。
原因:
- /status 会返回较多敏感主机信息
- 服务以高权限运行时,应尽量缩小默认暴露面
6. HostStatus 建议字段
建议返回统一 JSON 结构,主要包含以下字段:
- agent
- version
- started_at
- snapshot_at
- snapshot_status
- host
- host_id
- hostname
- platform
- platform_version
- arch
- uptime_seconds
- network
- interfaces[]
- name
- mac
- mtu
- flags
- addresses[]
- ips[]
- macs[]
- cpu
- logical_cores
- physical_cores
- usage_percent
- load_avg
- model_name
- memory
- total
- used
- free
- available
- used_percent
- disks[]
- device
- mount_point
- fs_type
- total
- used
- free
- used_percent
- processes
- status: ok | partial | error
- items[]
- pid
- ppid
- name
- exe
- cmdline
- username
- status
- start_time
- cpu_percent
- memory_rss
- memory_vms
- tcp_listeners
- status: ok | partial | error
- items[]
- ip
- port
- pid
- process_name
- process_exe
- family: ipv4 | ipv6
- errors[]
用于记录子采集器失败原因,例如:
- process.cmdline permission denied
7. 采集策略
建议采用“周期采集 + 内存缓存”:
- 启动后立即采集一次
- 后台定时刷新缓存
- HTTP 接口直接读取缓存,不在每次请求时实时扫描系统
- 主动上报也读取同一份缓存,避免重复采集
这样做的好处:
- 响应更快
- 降低系统扫描频率
- 避免进程列表和端口列表每次请求都重新采集
采集时建议设置:
- 整体采集超时
- 单个子采集器失败不拖垮整次快照
例如:
- 进程采集失败,仍返回 CPU、内存、磁盘等其他信息
- tcp_listeners 采集不完整时,将状态标记为 partial
8. 主动上报设计
agent 除了支持外部系统通过 HTTP 拉取状态,还支持定时主动上报。
建议方式:
- 配置一个固定中心服务 URL
- 周期性 POST HostStatus JSON
- 上报载荷直接复用 /status 的 JSON 结构
这样可以避免维护两套数据模型。
建议配置项:
- report.enabled
- report.endpoint
- report.interval
- report.timeout
上报失败策略:
- 超时和失败日志独立记录
- 支持重试或简单退避
- 上报失败不能影响本地 HTTP 服务
- 上报失败不能导致进程退出
9. CLI 设计
建议提供以下命令:
- agent run
- agent install
- agent uninstall
- agent start
- agent stop
- agent version
Linux:
- agent 进程以前台模式运行
- 额外提供 systemd unit 模板
- 安装脚本负责写入 unit 并启停
Windows:
- 使用服务包装库实现 install/uninstall/start/stop/run
- 不依赖外部 NSSM
10. 技术建议
推荐使用 Go 实现,原因:
- 单二进制,部署简单
- Windows 和 Linux 跨平台支持较好
- 服务化实现相对成熟
- 适合做常驻守护进程和 HTTP 服务
系统信息采集建议优先使用成熟跨平台库,例如:
- gopsutil
这样可以减少自己处理平台差异的工作量。
如库在“端口到进程映射”能力上不足,可以针对 Windows/Linux 做补充实现。
11. 测试建议
单元测试:
- 各采集器输出能正确映射为 HostStatus
- 进程列表和 TCP 监听项在空结果、部分字段缺失、权限错误时能输出 partial/error
- snapshot 聚合逻辑在部分采集失败时仍返回可用快照
集成测试:
- 启动后 GET /health 返回正常
- GET /status 返回完整 JSON,包含 cpu、processes、tcp_listeners
- 模拟中心端,验证 POST 的载荷、超时、失败重试行为
平台验证:
- Windows:服务安装、启动、停止、卸载
- Linux:systemd 安装、enable、start、restart
性能与稳定性:
- 大量进程场景下 /status 仍在可接受时间内返回
- 采集周期与 HTTP 并发访问同时存在时无明显阻塞
- /status 响应体较大时内存占用可控
12. 首版边界
首版默认包括:
- IP
- MAC
- 主机名
- CPU
- 内存
- 磁盘
- 完整进程列表
- TCP 监听端口及进程映射
- 本地 HTTP 查询
- 主动 HTTP 上报
- Windows/Linux 服务化
首版默认不包括:
- 历史存储
- 趋势分析
- 分页查询
- UDP 监听信息
- 线程列表
- 进程句柄
- 连接状态详情
- 强制 Token/mTLS
13. 结论
最务实的首版实现方案是:
- 使用 Go
- 单进程一体化架构
- 安装时管理员/root 权限
- 运行时默认高权限服务账户
- GET /status 单接口全量返回
- 默认监听 127.0.0.1
- 同时支持被动查询和主动上报
如果进入实现阶段,下一步可以直接开始定义:
- 配置文件结构
- HostStatus Go struct
- collector 接口
- Windows/Linux 服务安装与运行流程