mirror of
https://github.com/aziis98/statuspage.git
synced 2026-10-18 11:52:21 +00:00
Loads and expands the config, prints a per-group machine summary, and exits without starting the server (no db, probes, or ports needed). README flags table updated.
138 lines
3.6 KiB
Go
138 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
|
|
"github.com/joho/godotenv"
|
|
"github.com/spf13/pflag"
|
|
)
|
|
|
|
func envOr(key, def string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|
|
|
|
func printConfigSummary(path string, cfg *Config) {
|
|
byGroup := map[string]int{}
|
|
for _, m := range cfg.Machines {
|
|
byGroup[m.Group]++
|
|
}
|
|
log.Printf("config %s ok: %d machines", path, len(cfg.Machines))
|
|
for _, g := range cfg.Groups {
|
|
log.Printf(" %s: %d", g.Name, byGroup[g.Name])
|
|
}
|
|
if n := byGroup[""]; n > 0 {
|
|
log.Printf(" (top-level): %d", n)
|
|
}
|
|
}
|
|
|
|
func buildFrontend() error {
|
|
cmd := "npm"
|
|
if _, err := exec.LookPath("npm"); err != nil {
|
|
cmd = "bun"
|
|
}
|
|
c := exec.Command(cmd, "run", "build")
|
|
c.Stdout = os.Stdout
|
|
c.Stderr = os.Stderr
|
|
log.Printf("running %s run build", cmd)
|
|
return c.Run()
|
|
}
|
|
|
|
func spaHandler() http.Handler {
|
|
return http.FileServer(http.Dir("dist"))
|
|
}
|
|
|
|
func main() {
|
|
_ = godotenv.Load()
|
|
|
|
dev := pflag.Bool("dev", false, "run `npm run build` before serving dist/")
|
|
devServer := pflag.Bool("dev-server", false, "frontend served by the vite dev server, do not serve dist/")
|
|
mock := pflag.Bool("mock", false, "serve generated mock data instead of probing real machines")
|
|
check := pflag.Bool("check", false, "load and expand the config, print a machine summary, then exit")
|
|
addr := pflag.String("addr", envOr("ADDR", ":5000"), "listen address")
|
|
configPath := pflag.StringP("config", "c", envOr("CONFIG", "config.local.yaml"), "yaml config file")
|
|
dbPath := pflag.String("db", envOr("DB", "data.volume/history.db"), "sqlite history database file")
|
|
pflag.Parse()
|
|
|
|
if *check {
|
|
cfg, err := LoadConfig(*configPath)
|
|
if err != nil {
|
|
log.Fatalf("config check failed: %v", err)
|
|
}
|
|
printConfigSummary(*configPath, cfg)
|
|
return
|
|
}
|
|
|
|
if *dev {
|
|
if err := buildFrontend(); err != nil {
|
|
log.Fatalf("build failed: %v", err)
|
|
}
|
|
}
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
if *mock {
|
|
log.Printf("mock mode: serving generated data (no real probes)")
|
|
mm := NewMockMonitor()
|
|
mux.HandleFunc("GET /api/status", mm.statusHandler)
|
|
mux.HandleFunc("GET /api/history/{machine}", mm.historyHandler)
|
|
mux.HandleFunc("GET /api/metrics/aggregate", mm.metricsAggregateHandler)
|
|
mux.HandleFunc("GET /api/metrics/{machine}", mm.metricsHandler)
|
|
mux.HandleFunc("POST /api/refresh/{machine}", mm.refreshHandler)
|
|
if !*devServer {
|
|
mux.Handle("GET /", spaHandler())
|
|
}
|
|
log.Printf("listening on %s (mock)", *addr)
|
|
if err := http.ListenAndServe(*addr, mux); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return
|
|
}
|
|
|
|
if dir := filepath.Dir(*dbPath); dir != "." {
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
log.Fatalf("creating db dir: %v", err)
|
|
}
|
|
}
|
|
|
|
cfg, err := LoadConfig(*configPath)
|
|
if err != nil {
|
|
log.Fatalf("loading config: %v", err)
|
|
}
|
|
log.Printf("loaded %d machines from %s", len(cfg.Machines), *configPath)
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
history, err := NewHistory(*dbPath)
|
|
if err != nil {
|
|
log.Fatalf("opening history db: %v", err)
|
|
}
|
|
defer history.Close()
|
|
go history.pruneLoop(ctx)
|
|
|
|
mon := NewMonitor(cfg, history)
|
|
mon.Start(ctx)
|
|
|
|
mux.HandleFunc("GET /api/status", mon.statusHandler)
|
|
mux.HandleFunc("GET /api/history/{machine}", mon.historyHandler)
|
|
mux.HandleFunc("GET /api/metrics/aggregate", mon.metricsAggregateHandler)
|
|
mux.HandleFunc("GET /api/metrics/{machine}", mon.metricsHandler)
|
|
mux.HandleFunc("POST /api/refresh/{machine}", mon.refreshHandler)
|
|
if !*devServer {
|
|
mux.Handle("GET /", spaHandler())
|
|
}
|
|
|
|
log.Printf("listening on %s", *addr)
|
|
if err := http.ListenAndServe(*addr, mux); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|