From 3cf2d974a4422a46a2ce5bcc6104b2015c48088f Mon Sep 17 00:00:00 2001 From: root Date: Fri, 20 Mar 2026 10:02:11 +0000 Subject: [PATCH] fix: include CLI entrypoint in repository --- .gitignore | 2 +- cmd/harborforge-monitor/main.go | 98 +++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 cmd/harborforge-monitor/main.go diff --git a/.gitignore b/.gitignore index 44e5817..6b8769e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ bin/ dist/ -harborforge-monitor +/harborforge-monitor *.exe *.out *.test diff --git a/cmd/harborforge-monitor/main.go b/cmd/harborforge-monitor/main.go new file mode 100644 index 0000000..90d5259 --- /dev/null +++ b/cmd/harborforge-monitor/main.go @@ -0,0 +1,98 @@ +package main + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "log" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "git.hangman-lab.top/zhi/HarborForge.Monitor/internal/config" + "git.hangman-lab.top/zhi/HarborForge.Monitor/internal/telemetry" +) + +func main() { + var ( + configPath string + runOnce bool + printPayload bool + dryRun bool + showVersion bool + ) + flag.StringVar(&configPath, "config", "/etc/harborforge-monitor/config.json", "Path to config file") + flag.BoolVar(&runOnce, "once", false, "Collect and send telemetry once, then exit") + flag.BoolVar(&printPayload, "print-payload", false, "Print payload JSON before sending") + flag.BoolVar(&dryRun, "dry-run", false, "Collect telemetry but do not send it") + flag.BoolVar(&showVersion, "version", false, "Print version and exit") + flag.Parse() + + if showVersion { + fmt.Println(telemetry.Version) + return + } + + cfg, err := config.Load(configPath) + if err != nil { + log.Fatalf("load config: %v", err) + } + if cfg.APIKey == "" { + log.Fatalf("apiKey is required") + } + + logger := log.New(os.Stdout, "[harborforge-monitor] ", log.LstdFlags) + client := &http.Client{Timeout: 20 * time.Second} + + ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer stop() + + sendOnce := func() error { + payload, err := telemetry.BuildPayload(ctx, cfg) + if err != nil { + return err + } + if printPayload || dryRun { + buf, _ := json.MarshalIndent(payload, "", " ") + fmt.Println(string(buf)) + } + if dryRun { + logger.Printf("dry-run: telemetry collected for %s", cfg.Identifier) + return nil + } + if err := telemetry.Send(ctx, client, cfg, payload); err != nil { + return err + } + logger.Printf("heartbeat sent for %s", cfg.Identifier) + return nil + } + + if runOnce { + if err := sendOnce(); err != nil { + log.Fatalf("send once failed: %v", err) + } + return + } + + ticker := time.NewTicker(time.Duration(cfg.ReportIntervalSec) * time.Second) + defer ticker.Stop() + + if err := sendOnce(); err != nil { + logger.Printf("initial heartbeat failed: %v", err) + } + + for { + select { + case <-ctx.Done(): + logger.Printf("shutting down") + return + case <-ticker.C: + if err := sendOnce(); err != nil { + logger.Printf("heartbeat failed: %v", err) + } + } + } +}