package main import ( "bytes" "encoding/json" "fmt" "log" "net/http" "os" "path/filepath" "strconv" "time" "metis/pkg/sentinel" ) func main() { interval := time.Duration(getenvInt("METIS_SENTINEL_INTERVAL_SEC", 300)) * time.Second pushURL := os.Getenv("METIS_SENTINEL_PUSH_URL") runOnce := os.Getenv("METIS_SENTINEL_RUN_ONCE") == "1" for { snap := sentinel.Collect() enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") if err := enc.Encode(snap); err != nil { log.Fatalf("encode: %v", err) } if out := os.Getenv("METIS_SENTINEL_OUT"); out != "" { writeHistory(out, snap) } if pushURL != "" { if err := pushSnapshot(pushURL, snap); err != nil { log.Printf("push snapshot failed: %v", err) } } if runOnce || pushURL == "" { break } time.Sleep(interval) } } func writeHistory(path string, snap *sentinel.Snapshot) { if path == "" { return } if err := os.MkdirAll(path, 0o755); err != nil { return } ts := time.Now().UTC().Format("20060102T150405Z") b, _ := json.MarshalIndent(snap, "", " ") _ = os.WriteFile(filepath.Join(path, "snapshot-"+ts+".json"), b, 0o644) } func pushSnapshot(url string, snap *sentinel.Snapshot) error { payload := map[string]any{ "node": snap.Hostname, "collected_at": time.Now().UTC(), "snapshot": snap, } body, err := json.Marshal(payload) if err != nil { return err } req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body)) if err != nil { return err } req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode >= 300 { return fmt.Errorf("push snapshot: %s", resp.Status) } return nil } func getenvInt(key string, fallback int) int { if raw := os.Getenv(key); raw != "" { if value, err := strconv.Atoi(raw); err == nil { return value } } return fallback }