package main import ( "context" "embed" "flag" "html/template" "log" "net/http" "os" "os/signal" "strconv" "syscall" ) //go:embed templates var templatesFS embed.FS func main() { listen := flag.String("listen", envOr("FRONTEND_LISTEN", ":8080"), "HTTP listen address (env: FRONTEND_LISTEN)") target := flag.String("target", envOr("FRONTEND_TARGET", "localhost:9091"), "default gRPC endpoint, aggregator or collector (env: FRONTEND_TARGET)") n := flag.Int("n", envOrInt("FRONTEND_N", 25), "default number of table rows (env: FRONTEND_N)") refresh := flag.Int("refresh", envOrInt("FRONTEND_REFRESH", 30), "meta-refresh interval in seconds, 0 to disable (env: FRONTEND_REFRESH)") flag.Parse() funcMap := template.FuncMap{"fmtCount": fmtCount} tmpl := template.Must( template.New("").Funcs(funcMap).ParseFS(templatesFS, "templates/*.html"), ) h := &Handler{ defaultTarget: *target, defaultN: *n, refreshSecs: *refresh, tmpl: tmpl, } srv := &http.Server{Addr: *listen, Handler: h} ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() go func() { log.Printf("frontend: listening on %s (default target %s)", *listen, *target) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Printf("frontend: %v", err) os.Exit(1) } }() <-ctx.Done() log.Printf("frontend: shutting down") srv.Shutdown(context.Background()) } func envOr(key, def string) string { if v := os.Getenv(key); v != "" { return v } return def } func envOrInt(key string, def int) int { if v := os.Getenv(key); v != "" { if n, err := strconv.Atoi(v); err == nil { return n } log.Printf("frontend: invalid int for %s=%q, using default %d", key, v, def) } return def }