✨ feat(agent): 添加 token 鉴权和流程文档

* 默认监听调整为 0.0.0.0:8080,并要求查询参数 token
* 支持首次 run 自动生成含随机 token 的配置文件
* 补充 HTTP 鉴权、配置校验和相关测试
* 完善代码注释,覆盖缓存、上报、服务和平台采集路径
* 新增架构与开发流程文档,补充一键构建脚本
This commit is contained in:
codex
2026-05-22 06:46:21 +00:00
parent 877e4cf41d
commit de3fd88948
19 changed files with 875 additions and 125 deletions

View File

@@ -20,6 +20,7 @@ import (
"mfd-monitor-agent/internal/snapshot"
)
// version 是编译时可通过 -ldflags 覆盖的 agent 版本号。
var version = "0.1.0"
// main 运行 CLI,命令失败时以非零状态退出。
@@ -42,7 +43,8 @@ func runCLI(args []string) error {
if err := fs.Parse(args[1:]); err != nil {
return err
}
cfg, err := config.Load(*configPath)
path := config.ResolvePath(*configPath)
cfg, err := config.LoadOrCreate(path)
if err != nil {
return err
}
@@ -87,18 +89,20 @@ func commandConfig(args []string) (config.Config, string, string, error) {
if err := fs.Parse(args); err != nil {
return config.Config{}, "", "", err
}
cfg, err := config.Load(*configPath)
path := config.ResolvePath(*configPath)
cfg, err := config.Load(path)
if err != nil {
return cfg, "", "", err
}
executable := *executableFlag
if executable == "" {
// 服务安装需要写入一个稳定的二进制路径;未显式传入时使用当前进程路径。
executable, err = os.Executable()
if err != nil {
return cfg, "", "", err
}
}
return cfg, executable, *configPath, nil
return cfg, executable, path, nil
}
// runAgent 启动采集、可选上报与本地 HTTP API,直至收到退出信号。
@@ -109,20 +113,23 @@ func runAgent(cfg config.Config) error {
startedAt := time.Now().UTC()
cache := snapshot.NewCache(collector.New(cfg.HostID), version, startedAt)
// 采集在后台立即执行一次并周期刷新,HTTP 与上报都只读取这份缓存。
go cache.Run(ctx, cfg.Collect.Interval.Duration(), cfg.Collect.Timeout.Duration())
if cfg.Report.Enabled {
client := reporter.NewClient(cfg.Report.Endpoint, cfg.Report.Timeout.Duration())
// 上报循环独立于 HTTP 服务运行;失败只记录日志并重试,不终止 agent。
go reporter.Run(ctx, cache, client, cfg.Report.Interval.Duration(), logger)
}
server := &http.Server{
Addr: cfg.HTTP.ListenAddress,
Handler: httpapi.New(cache),
Handler: httpapi.New(cache, cfg.HTTP.Token),
ReadHeaderTimeout: 5 * time.Second,
}
go func() {
<-ctx.Done()
// 收到系统信号后给 HTTP 请求一个短暂宽限期,避免直接中断正在返回的快照。
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_ = server.Shutdown(shutdownCtx)