common/health/health_server.go

61 lines
1.2 KiB
Go

package health
import (
"context"
"net/http"
"strconv"
"time"
"golang.org/x/exp/slog"
"golang.org/x/sync/errgroup"
)
// HealthCheckListener runs simple http server on the specified port for
// health check probes
func HealthCheckListener(ctx context.Context, port int, log *slog.Logger) error {
log.Info("Starting health listener", "port", port)
serveMux := http.NewServeMux()
serveMux.HandleFunc("/__health", basicHealth)
srv := &http.Server{
Addr: ":" + strconv.Itoa(port),
ReadTimeout: 10 * time.Second,
WriteTimeout: 20 * time.Second,
IdleTimeout: 120 * time.Second,
Handler: serveMux,
}
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
err := srv.ListenAndServe()
if err != http.ErrServerClosed {
log.Warn("health check server done listening", "err", err)
return err
}
return nil
})
<-ctx.Done()
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
g.Go(func() error {
if err := srv.Shutdown(ctx); err != nil {
log.Error("health check server shutdown failed", "err", err)
return err
}
return nil
})
return g.Wait()
}
func basicHealth(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("ok"))
}