error-pages/internal/http/middleware/logreq/middleware.go
2024-07-03 18:12:13 +04:00

62 lines
1.7 KiB
Go

package logreq
import (
"time"
"github.com/valyala/fasthttp"
"gh.tarampamp.am/error-pages/internal/logger"
)
// New creates a middleware that logs every incoming request.
//
// The skipper function should return true if the request should be skipped. It's ok to pass nil.
func New(
log *logger.Logger,
skipper func(*fasthttp.RequestCtx) bool,
) func(fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(next fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
if skipper != nil && skipper(ctx) {
next(ctx)
return
}
var now = time.Now()
defer func() {
var fields = []logger.Attr{
logger.Int("status code", ctx.Response.StatusCode()),
logger.String("useragent", string(ctx.UserAgent())),
logger.String("method", string(ctx.Method())),
logger.String("url", string(ctx.RequestURI())),
logger.String("referer", string(ctx.Referer())),
logger.String("content type", string(ctx.Response.Header.ContentType())),
logger.String("remote addr", ctx.RemoteAddr().String()),
logger.Duration("duration", time.Since(now).Round(time.Microsecond)),
}
if log.Level() <= logger.DebugLevel {
var (
reqHeaders = make(map[string]string)
respHeaders = make(map[string]string)
)
ctx.Request.Header.VisitAll(func(key, value []byte) { reqHeaders[string(key)] = string(value) })
ctx.Response.Header.VisitAll(func(key, value []byte) { respHeaders[string(key)] = string(value) })
fields = append(fields,
logger.Any("request headers", reqHeaders),
logger.Any("response headers", respHeaders),
)
}
log.Info("HTTP request processed", fields...)
}()
next(ctx)
}
}
}