// Command admind is the admin HTTP API + (later) UI host. Tenant CRUD, // DLQ inspection, replay, audit log. M0: /health, /metrics, /v1/ping. package main import ( "context" "encoding/json" "net/http" "os" "os/signal" "syscall" "time" "git3.techno-world.net/lrosales/broad-announce/internal/config" "git3.techno-world.net/lrosales/broad-announce/internal/httpserver" "git3.techno-world.net/lrosales/broad-announce/internal/observability" ) func main() { cfg, err := config.LoadCommon("admind") if err != nil { os.Stderr.WriteString("config: " + err.Error() + "\n") os.Exit(1) } logger := observability.Init(cfg.Env, cfg.LogLevel, "admind") logger.Info("starting", "env", cfg.Env, "addr", cfg.HTTPAddr) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() reg, _ := observability.NewRegistry("admind") srv := httpserver.New(httpserver.Config{ Addr: cfg.HTTPAddr, ServiceName: "admind", ShutdownGrace: cfg.ShutdownGrace, }, logger, observability.MetricsHandler(reg)) srv.Mux().HandleFunc("GET /v1/ping", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]any{ "pong": true, "service": "admind", "timestamp": time.Now().UTC().Format(time.RFC3339Nano), }) }) errCh := make(chan error, 1) go func() { errCh <- srv.Start() }() select { case <-ctx.Done(): logger.Info("shutdown signal received") case err := <-errCh: if err != nil { logger.Error("http server", "err", err) os.Exit(1) } } if err := srv.Shutdown(ctx); err != nil { logger.Warn("graceful shutdown", "err", err) } logger.Info("bye") }