From da95c21b24bd8bf7061add1da7438cfa199c5427 Mon Sep 17 00:00:00 2001 From: Rene Zbinden Date: Mon, 28 Nov 2022 12:26:07 +0100 Subject: [PATCH] feat: add logfmt support --- flash.go | 90 ++++++++++++++++++++++++++++++--------------------- flash_test.go | 9 ++++++ go.mod | 1 + go.sum | 8 +++++ 4 files changed, 72 insertions(+), 36 deletions(-) diff --git a/flash.go b/flash.go index 717e742..32335e3 100644 --- a/flash.go +++ b/flash.go @@ -10,6 +10,7 @@ import ( "github.com/mattn/go-isatty" "github.com/prometheus/client_golang/prometheus" + zaplogfmt "github.com/sykesm/zap-logfmt" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" @@ -26,6 +27,7 @@ type EncoderType int const ( Console EncoderType = iota JSON + LogFmt ) // Logger is the flash logger which embeds a `zap.SugaredLogger`. @@ -144,7 +146,8 @@ func New(opts ...Option) *Logger { } // set encoder to json and disable color output when no terminal is detected - if !isatty.IsTerminal(os.Stdout.Fd()) { + // and encoder is not LogFmt + if !isatty.IsTerminal(os.Stdout.Fd()) && cfg.encoder != LogFmt { cfg.encoder = JSON cfg.enableColor = false } @@ -157,43 +160,9 @@ func New(opts ...Option) *Logger { cfg.enableColor = false } - zapConfig := zap.NewProductionConfig() - zapConfig.DisableStacktrace = cfg.disableStacktrace - zapConfig.Sampling = nil - zapConfig.DisableCaller = cfg.disableCaller - zapConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - zapConfig.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder - zapConfig.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder + zapConfig := genZapConfig(cfg) zapConfig.Level = atom - switch cfg.encoder { - case Console: - zapConfig.Encoding = "console" - case JSON: - zapConfig.Encoding = "json" - } - - // no colors when logging to file - if cfg.enableColor && cfg.fileConfig == nil { - zapConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder - } - - if len(cfg.sinks) > 0 { - zapConfig.OutputPaths = cfg.sinks - } - - if cfg.disableTimestamps { - zapConfig.EncoderConfig.TimeKey = "" - } - - if cfg.fileConfig != nil { - if err := cfg.registerFileSink(); err != nil { - panic(err) - } - - zapConfig.OutputPaths = []string{cfg.fileConfig.sinkURI()} - } - var err error l, err = zapConfig.Build() @@ -327,3 +296,52 @@ func (c config) registerFileSink() error { }, nil }) } + +func genZapConfig(cfg config) zap.Config { + zapConfig := zap.NewProductionConfig() + zapConfig.DisableStacktrace = cfg.disableStacktrace + zapConfig.Sampling = nil + zapConfig.DisableCaller = cfg.disableCaller + zapConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + zapConfig.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder + zapConfig.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder + + switch cfg.encoder { + case Console: + zapConfig.Encoding = "console" + case JSON: + zapConfig.Encoding = "json" + case LogFmt: + zapConfig.Encoding = "logfmt" + _ = zap.RegisterEncoder("logfmt", func(cfg zapcore.EncoderConfig) (zapcore.Encoder, error) { + return zaplogfmt.NewEncoder(cfg), nil + }) + } + + // no colors when logging to file + if cfg.enableColor && cfg.fileConfig == nil { + zapConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + } + + if len(cfg.sinks) > 0 { + zapConfig.OutputPaths = cfg.sinks + } + + if cfg.disableTimestamps { + zapConfig.EncoderConfig.TimeKey = "" + } + + if cfg.fileConfig != nil { + if err := cfg.registerFileSink(); err != nil { + panic(err) + } + + zapConfig.OutputPaths = []string{cfg.fileConfig.sinkURI()} + } + + if cfg.disableTimestamps { + zapConfig.EncoderConfig.TimeKey = "" + } + + return zapConfig +} diff --git a/flash_test.go b/flash_test.go index b476ae3..a6b1e46 100644 --- a/flash_test.go +++ b/flash_test.go @@ -91,6 +91,15 @@ func TestWithoutCaller(t *testing.T) { assert.Empty(t, e[0].Caller) } +func TestLogFmt(t *testing.T) { + defer sink.Reset() + + l := flash.New(flash.WithSinks("memory://"), flash.WithEncoder(flash.LogFmt), flash.WithoutTimestamps()) + l.Info("info") + require.NotEmpty(t, sink.String()) + assert.Equal(t, "level=INFO caller=flash/flash_test.go:98 msg=info\n", sink.String()) +} + func TestWithStacktraceWithDebug(t *testing.T) { defer sink.Reset() diff --git a/go.mod b/go.mod index 743fb2c..99a9f0d 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/mattn/go-isatty v0.0.16 github.com/prometheus/client_golang v1.13.0 github.com/stretchr/testify v1.8.0 + github.com/sykesm/zap-logfmt v0.0.4 github.com/tj/assert v0.0.3 go.uber.org/zap v1.23.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0 diff --git a/go.sum b/go.sum index ba650ca..5fe70cc 100644 --- a/go.sum +++ b/go.sum @@ -207,6 +207,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/sykesm/zap-logfmt v0.0.4 h1:U2WzRvmIWG1wDLCFY3sz8UeEmsdHQjHFNlIdmroVFaI= +github.com/sykesm/zap-logfmt v0.0.4/go.mod h1:AuBd9xQjAe3URrWT1BBDk2v2onAZHkZkWRMiYZXiZWA= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -218,12 +220,16 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -385,6 +391,8 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=