package server import ( "context" "net/http" "sync" "time" "git.1in9.net/raider/wroofauth/internal/logger" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/viper" "go.uber.org/zap" ) var ( server *http.Server ) func startHttpServer(wg *sync.WaitGroup, r *chi.Mux) *http.Server { wg.Add(1) srv := &http.Server{ Handler: r, Addr: viper.GetString("http.listen"), WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } go func() { defer wg.Done() logger.Logger.Info("http server started", zap.String("listen", srv.Addr)) // Ignore ServerClosed Error if err := srv.ListenAndServe(); err != http.ErrServerClosed { logger.Logger.Fatal("http server error", zap.Error(err)) } logger.Logger.Info("http server stopped") }() return srv } func Shutdown(ctx context.Context) { if server == nil { return } if err := server.Shutdown(ctx); err != nil { logger.Logger.Panic("failed to gracefully stop http server", zap.Error(err)) } } func Serve() { r := chi.NewRouter() r.Use(middleware.RequestID) r.Use(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { wrappedResponse := middleware.NewWrapResponseWriter(w, r.ProtoMajor) latencyStart := time.Now() defer func() { latency := time.Since(latencyStart) logger.Logger.Debug("http request served", zap.String("proto", r.Proto), zap.String("uri", r.RequestURI), zap.String("path", r.URL.Path), zap.String("method", r.Method), zap.String("remote", r.RemoteAddr), zap.Int("status", wrappedResponse.Status()), zap.Int("size", wrappedResponse.BytesWritten()), zap.Duration("latency", latency), zap.String("requestId", middleware.GetReqID(r.Context())), ) }() next.ServeHTTP(wrappedResponse, r) }) }) r.Use(middleware.Recoverer) r.Use(middleware.Timeout(60 * time.Second)) r.Handle("/metrics", promhttp.Handler()) r.Mount("/api", SetupAPI()) httpServerExitDone := &sync.WaitGroup{} server = startHttpServer(httpServerExitDone, r) httpServerExitDone.Wait() // Wait for web server to shut down }