Added basic logfmt middleware

This commit is contained in:
Maxim Lebedev 2022-01-07 03:41:57 +05:00
parent 9b3bdd440f
commit 47e3c75ead
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
3 changed files with 90 additions and 2 deletions

3
go.mod
View File

@ -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
View File

@ -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=

84
logfmt.go Normal file
View File

@ -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()
}
}