diff --git a/go.mod b/go.mod index e9e2c19..79d81d0 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,12 @@ module gitlab.com/mstarongitlab/goutils go 1.19 + +require github.com/rs/zerolog v1.33.0 + +require ( + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/rs/xid v1.5.0 // indirect + golang.org/x/sys v0.12.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..36db2d7 --- /dev/null +++ b/go.sum @@ -0,0 +1,16 @@ +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/middleware/chain.go b/middleware/chain.go new file mode 100644 index 0000000..2cf765e --- /dev/null +++ b/middleware/chain.go @@ -0,0 +1,16 @@ +package middleware + +import ( + "net/http" + "slices" +) + +type HandlerBuilder func(http.Handler) http.Handler + +func ChainMiddlewares(base http.Handler, links ...HandlerBuilder) http.Handler { + slices.Reverse(links) + for _, f := range links { + base = f(base) + } + return base +} diff --git a/middleware/context.go b/middleware/context.go new file mode 100644 index 0000000..2df158c --- /dev/null +++ b/middleware/context.go @@ -0,0 +1,19 @@ +package middleware + +import ( + "context" + "net/http" +) + +func ContextValsMiddleware(pairs map[any]any) HandlerBuilder { + return func(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + for key, val := range pairs { + ctx = context.WithValue(ctx, key, val) + } + newRequest := r.WithContext(ctx) + h.ServeHTTP(w, newRequest) + }) + } +} diff --git a/middleware/zerolog.go b/middleware/zerolog.go new file mode 100644 index 0000000..04a9eaf --- /dev/null +++ b/middleware/zerolog.go @@ -0,0 +1,32 @@ +package middleware + +import ( + "net/http" + "strings" + "time" + + "github.com/rs/zerolog/hlog" + "github.com/rs/zerolog/log" +) + +func LoggingMiddleware(handler http.Handler) http.Handler { + return ChainMiddlewares(handler, + hlog.NewHandler(log.Logger), + hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) { + if strings.HasPrefix(r.URL.Path, "/assets") { + return + } + hlog.FromRequest(r).Info(). + Str("method", r.Method). + Stringer("url", r.URL). + Int("status", status). + Int("size", size). + Dur("duration", duration). + Send() + }), + hlog.RemoteAddrHandler("ip"), + hlog.UserAgentHandler("user_agent"), + hlog.RefererHandler("referer"), + hlog.RequestIDHandler("req_id", "Request-Id"), + ) +}