goutils/http/zerolog.go
mStar 4eb5d68fbf
Fix for the fix
I didn't actually write the found ip to the logging stack (or whatever
zerolog uses). This is now fixed
2025-05-12 15:35:45 +02:00

100 lines
2.6 KiB
Go

package webutils
import (
"net/http"
"strings"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/hlog"
"github.com/rs/zerolog/log"
)
func BuildLoggingMiddleware(
status500IsError bool,
ignorePaths []string,
extras map[string]string,
) HandlerBuilder {
return func(h http.Handler) http.Handler {
return ChainMiddlewares(h,
hlog.NewHandler(log.Logger),
hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
for _, p := range ignorePaths {
if strings.HasPrefix(r.URL.Path, p) {
return
}
}
var logger *zerolog.Event
if status >= 500 {
if status500IsError {
logger = hlog.FromRequest(r).Error()
} else {
logger = hlog.FromRequest(r).Warn()
}
} else {
logger = hlog.FromRequest(r).Info()
}
logger = logger.
Str("method", r.Method).
Stringer("url", r.URL).
Int("status", status).
Int("size", size).
Dur("duration", duration)
for k, v := range extras {
logger = logger.Str(k, v)
}
logger.Send()
}),
RealIpAppenderMiddleware("ip"),
hlog.UserAgentHandler("user_agent"),
hlog.RefererHandler("referer"),
hlog.RequestIDHandler("req_id", "Request-Id"),
)
}
}
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()
}),
RealIpAppenderMiddleware("ip"),
hlog.UserAgentHandler("user_agent"),
hlog.RefererHandler("referer"),
hlog.RequestIDHandler("req_id", "Request-Id"),
)
}
// hlog.RemoteAddrHandler except fixed to check the X-Real-Ip and X-Forwarded-For
// headers first for the IP instead of relying on RemoteAddr
// (which would only return the last proxy's address instead of the caller's)
func RealIpAppenderMiddleware(fieldKey string) func(handler http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
IPAddress := r.Header.Get("X-Real-Ip")
if IPAddress == "" {
IPAddress = r.Header.Get("X-Forwarded-For")
}
if IPAddress == "" {
IPAddress = r.RemoteAddr
}
if IPAddress != "" {
log := zerolog.Ctx(r.Context())
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
return c.Str(fieldKey, IPAddress)
})
}
next.ServeHTTP(w, r)
})
}
}