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

8.6 KiB
Raw Permalink Blame History

高权限主机状态 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。

  1. 目标

开发一个独立的 Go 单二进制 agent,支持安装为 Windows Service 和 Linux systemd service。

安装阶段要求管理员/root;首版运行阶段也默认使用高权限账户,以稳定采集完整主机信息。

agent 对外提供 HTTP 接口,核心接口为 GET /status,单次返回完整主机状态快照,包含:

  • IP
  • MAC
  • 主机名
  • CPU
  • 内存
  • 磁盘
  • 完整进程列表
  • 监听中的 TCP 端口及其进程映射

同时 agent 支持按周期向中心端固定 HTTP 接口主动上报同一份状态 JSON。

  1. 服务权限说明

注册为服务这一步基本都需要管理员权限:

  • Windows:创建、删除、启动、停止 Windows Service 需要管理员权限
  • Linux:写入 systemd unit、systemctl enable/start 通常需要 root

服务运行阶段:

  • 如果只读取主机名、IP、MAC、内存、磁盘、CPU,通常不一定需要管理员权限
  • 但如果要稳定获取完整进程列表,以及监听 TCP 端口和进程映射,建议服务默认也以高权限运行

建议首版权限策略:

  • 安装阶段:必须管理员/root
  • 运行阶段:默认高权限运行
  • 接口层:即使某些字段采集失败,也不要让整个 /status 失败,应返回 partial 或错误原因
  1. 架构方案

推荐使用“单进程一体化”架构。

一个 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:统一加载监听地址、采集周期、上报周期、上报目标、机器标识等配置
  1. HTTP 接口设计

建议保留两个接口:

  • GET /health 用于返回进程存活、版本、最近快照时间、最近采集状态

  • GET /status 返回完整 HostStatus

根据当前确认的需求,/status 采用单接口全量返回,不拆分接口,不使用 include 参数。

默认监听地址建议为:

  • 127.0.0.1

如果后续需要局域网访问,再通过配置改为指定内网地址。

原因:

  • /status 会返回较多敏感主机信息
  • 服务以高权限运行时,应尽量缩小默认暴露面
  1. 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
  1. 采集策略

建议采用“周期采集 + 内存缓存”:

  • 启动后立即采集一次
  • 后台定时刷新缓存
  • HTTP 接口直接读取缓存,不在每次请求时实时扫描系统
  • 主动上报也读取同一份缓存,避免重复采集

这样做的好处:

  • 响应更快
  • 降低系统扫描频率
  • 避免进程列表和端口列表每次请求都重新采集

采集时建议设置:

  • 整体采集超时
  • 单个子采集器失败不拖垮整次快照

例如:

  • 进程采集失败,仍返回 CPU、内存、磁盘等其他信息
  • tcp_listeners 采集不完整时,将状态标记为 partial
  1. 主动上报设计

agent 除了支持外部系统通过 HTTP 拉取状态,还支持定时主动上报。

建议方式:

  • 配置一个固定中心服务 URL
  • 周期性 POST HostStatus JSON
  • 上报载荷直接复用 /status 的 JSON 结构

这样可以避免维护两套数据模型。

建议配置项:

  • report.enabled
  • report.endpoint
  • report.interval
  • report.timeout

上报失败策略:

  • 超时和失败日志独立记录
  • 支持重试或简单退避
  • 上报失败不能影响本地 HTTP 服务
  • 上报失败不能导致进程退出
  1. 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
  1. 技术建议

推荐使用 Go 实现,原因:

  • 单二进制,部署简单
  • Windows 和 Linux 跨平台支持较好
  • 服务化实现相对成熟
  • 适合做常驻守护进程和 HTTP 服务

系统信息采集建议优先使用成熟跨平台库,例如:

  • gopsutil

这样可以减少自己处理平台差异的工作量。

如库在“端口到进程映射”能力上不足,可以针对 Windows/Linux 做补充实现。

  1. 测试建议

单元测试:

  • 各采集器输出能正确映射为 HostStatus
  • 进程列表和 TCP 监听项在空结果、部分字段缺失、权限错误时能输出 partial/error
  • snapshot 聚合逻辑在部分采集失败时仍返回可用快照

集成测试:

  • 启动后 GET /health 返回正常
  • GET /status 返回完整 JSON,包含 cpu、processes、tcp_listeners
  • 模拟中心端,验证 POST 的载荷、超时、失败重试行为

平台验证:

  • Windows:服务安装、启动、停止、卸载
  • Linux:systemd 安装、enable、start、restart

性能与稳定性:

  • 大量进程场景下 /status 仍在可接受时间内返回
  • 采集周期与 HTTP 并发访问同时存在时无明显阻塞
  • /status 响应体较大时内存占用可控
  1. 首版边界

首版默认包括:

  • IP
  • MAC
  • 主机名
  • CPU
  • 内存
  • 磁盘
  • 完整进程列表
  • TCP 监听端口及进程映射
  • 本地 HTTP 查询
  • 主动 HTTP 上报
  • Windows/Linux 服务化

首版默认不包括:

  • 历史存储
  • 趋势分析
  • 分页查询
  • UDP 监听信息
  • 线程列表
  • 进程句柄
  • 连接状态详情
  • 强制 Token/mTLS
  1. 结论

最务实的首版实现方案是:

  • 使用 Go
  • 单进程一体化架构
  • 安装时管理员/root 权限
  • 运行时默认高权限服务账户
  • GET /status 单接口全量返回
  • 默认监听 127.0.0.1
  • 同时支持被动查询和主动上报

如果进入实现阶段,下一步可以直接开始定义:

  • 配置文件结构
  • HostStatus Go struct
  • collector 接口
  • Windows/Linux 服务安装与运行流程