✨ Added basic logfmt middleware
This commit is contained in:
parent
9b3bdd440f
commit
47e3c75ead
3
go.mod
3
go.mod
|
@ -4,6 +4,7 @@ go 1.17
|
|||
|
||||
require (
|
||||
github.com/fasthttp/session/v2 v2.4.4
|
||||
github.com/go-logfmt/logfmt v0.5.1
|
||||
github.com/lestrrat-go/jwx v1.2.14
|
||||
github.com/valyala/fasthttp v1.31.0
|
||||
)
|
||||
|
@ -11,7 +12,7 @@ require (
|
|||
require (
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||
github.com/goccy/go-json v0.8.1 // indirect
|
||||
github.com/goccy/go-json v0.9.0 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.0 // indirect
|
||||
|
|
5
go.sum
5
go.sum
|
@ -15,11 +15,14 @@ github.com/fasthttp/session/v2 v2.4.4 h1:xJOyPT8oIAeDXwCDnDyz52x44BxVRTCRNhYeMNj
|
|||
github.com/fasthttp/session/v2 v2.4.4/go.mod h1:qemCSBS6ozHzh5RVPMQzAFklcAhLqLtsoGTz1OPT5kM=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI=
|
||||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.9.0 h1:2flW7bkbrRgU8VuDi0WXDqTmPimjv1thfxkPe8sug+8=
|
||||
github.com/goccy/go-json v0.9.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-logfmt/logfmt"
|
||||
http "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
type LogFmtConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
|
||||
// TODO(toby3d): allow select some tags
|
||||
|
||||
// Output is a writer where logs in JSON format are written.
|
||||
// Optional. Default value os.Stdout.
|
||||
Output io.Writer
|
||||
}
|
||||
|
||||
var DefaultLogFmtConfig = LogFmtConfig{
|
||||
Skipper: DefaultSkipper,
|
||||
Output: os.Stdout,
|
||||
}
|
||||
|
||||
func LogFmt() Interceptor {
|
||||
c := DefaultLogFmtConfig
|
||||
|
||||
return LogFmtWithConfig(c)
|
||||
}
|
||||
|
||||
func LogFmtWithConfig(config LogFmtConfig) Interceptor {
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultLogFmtConfig.Skipper
|
||||
}
|
||||
|
||||
if config.Output == nil {
|
||||
config.Output = DefaultLogFmtConfig.Output
|
||||
}
|
||||
|
||||
encoder := logfmt.NewEncoder(config.Output)
|
||||
|
||||
return func(ctx *http.RequestCtx, next http.RequestHandler) {
|
||||
next(ctx)
|
||||
|
||||
encoder.EncodeKeyvals(
|
||||
"bytes_in", len(ctx.Request.Body()),
|
||||
"bytes_out", len(ctx.Response.Body()),
|
||||
"error", ctx.Err(),
|
||||
"host", ctx.Host(),
|
||||
"id", ctx.ID(),
|
||||
"latency", ctx.Time().Sub(ctx.ConnTime()).Nanoseconds(),
|
||||
"latency_human", ctx.Time().Sub(ctx.ConnTime()).String(),
|
||||
"method", ctx.Method(),
|
||||
"path", ctx.Path(),
|
||||
"protocol", ctx.Request.Header.Protocol(),
|
||||
"referer", ctx.Referer(),
|
||||
"remote_ip", ctx.RemoteIP(),
|
||||
"status", ctx.Response.StatusCode(),
|
||||
"time_rfc3339", ctx.Time().Format(time.RFC3339),
|
||||
"time_rfc3339_nano", ctx.Time().Format(time.RFC3339Nano),
|
||||
"time_unix", ctx.Time().Unix(),
|
||||
"time_unix_nano", ctx.Time().UnixNano(),
|
||||
"uri", ctx.URI(),
|
||||
"user_agent", ctx.UserAgent(),
|
||||
)
|
||||
ctx.Request.Header.VisitAllInOrder(func(key, value []byte) {
|
||||
encoder.EncodeKeyval("header_"+string(key), value)
|
||||
})
|
||||
ctx.QueryArgs().VisitAll(func(key, value []byte) {
|
||||
encoder.EncodeKeyval("query_"+string(key), value)
|
||||
})
|
||||
|
||||
if form, err := ctx.MultipartForm(); err == nil {
|
||||
for k, v := range form.Value {
|
||||
encoder.EncodeKeyval("form_"+k, v)
|
||||
}
|
||||
}
|
||||
|
||||
encoder.EndRecord()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue