wroofauth/internal/server/server.go
2023-11-30 09:53:40 +00:00

96 lines
2.2 KiB
Go

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
}