package server import ( "context" "net/http" "time" "github.com/prometheus/client_golang/prometheus/promhttp" "go.uber.org/zap" ) // ListenAndServe starts a web server and waits for SIGTERM func ListenAndServe(port string, timeout time.Duration, logger *zap.SugaredLogger, stopCh <-chan struct{}) { mux := http.DefaultServeMux mux.Handle("/metrics", promhttp.Handler()) mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) }) srv := &http.Server{ Addr: ":" + port, Handler: mux, ReadTimeout: 5 * time.Second, WriteTimeout: 1 * time.Minute, IdleTimeout: 15 * time.Second, } logger.Infof("Starting HTTP server on port %s", port) // run server in background go func() { if err := srv.ListenAndServe(); err != http.ErrServerClosed { logger.Fatalf("HTTP server crashed %v", err) } }() // wait for SIGTERM or SIGINT <-stopCh ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() if err := srv.Shutdown(ctx); err != nil { logger.Errorf("HTTP server graceful shutdown failed %v", err) } else { logger.Info("HTTP server stopped") } }