diff --git a/main.go b/main.go new file mode 100644 index 0000000..a792d9c --- /dev/null +++ b/main.go @@ -0,0 +1,66 @@ +// Dash is a single-binary uptime monitoring dashboard. +package main + +import ( + "context" + "errors" + "flag" + "log" + "net/http" + "os/signal" + "syscall" + "time" + + "dash/internal/api" + "dash/internal/config" + "dash/internal/engine" + "dash/internal/store" +) + +func main() { + configPath := flag.String("config", "targets.yaml", "path to targets.yaml") + listen := flag.String("listen", "", "listen address (overrides config)") + dbPath := flag.String("db", "", "sqlite database path (overrides config)") + flag.Parse() + + cfg, err := config.Load(*configPath) + if err != nil { + log.Fatalf("config: %v", err) + } + if *listen != "" { + cfg.Settings.Listen = *listen + } + if *dbPath != "" { + cfg.Settings.DB = *dbPath + } + + st, err := store.Open(cfg.Settings.DB) + if err != nil { + log.Fatalf("store: %v", err) + } + defer st.Close() + + ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer stop() + + hub := engine.NewHub() + eng := engine.New(cfg, st, hub) + go eng.Run(ctx) + + mux := http.NewServeMux() + api.New(eng, st, hub).Register(mux) + mux.Handle("/", webHandler()) + + srv := &http.Server{Addr: cfg.Settings.Listen, Handler: mux} + go func() { + <-ctx.Done() + shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + srv.Shutdown(shutdownCtx) + }() + + log.Printf("dash listening on %s — monitoring %d targets", cfg.Settings.Listen, len(cfg.Targets)) + if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { + log.Fatalf("server: %v", err) + } +}