From 087ac2336df670ef912196a0670c7d8963b11935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Aguilar=20Y=C3=A9pez?= Date: Wed, 17 Apr 2024 15:37:43 -0600 Subject: [PATCH] feat: zerolog writer (#23) * feat: add zerolog writer methods * fix: stack trace --- adapters/zerolog/go.mod | 2 +- adapters/zerolog/go.sum | 4 +- adapters/zerolog/options.go | 16 +++--- adapters/zerolog/options_test.go | 11 ---- adapters/zerolog/zerolog.go | 87 ++++++++++++++++++++++---------- 5 files changed, 71 insertions(+), 49 deletions(-) diff --git a/adapters/zerolog/go.mod b/adapters/zerolog/go.mod index fbeb633..8050501 100644 --- a/adapters/zerolog/go.mod +++ b/adapters/zerolog/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/danteay/golog/fields v0.1.0 - github.com/danteay/golog/levels v0.1.0 + github.com/danteay/golog/levels v0.1.1 github.com/rs/zerolog v1.32.0 github.com/stretchr/testify v1.9.0 ) diff --git a/adapters/zerolog/go.sum b/adapters/zerolog/go.sum index 741dba1..e62e058 100644 --- a/adapters/zerolog/go.sum +++ b/adapters/zerolog/go.sum @@ -1,8 +1,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/danteay/golog/fields v0.1.0 h1:/W3Gh3PrVoJsY53sear+yzyLRkIMkM039lOfSNfUFj0= github.com/danteay/golog/fields v0.1.0/go.mod h1:ACO2Sinx9OSYgwgUVTSZtWaT1q0VzHes6cDVgJtOS4Q= -github.com/danteay/golog/levels v0.1.0 h1:vJqNEKlij90z6b7PSq6bqxmV9KbKn1tj8nlkASl0r14= -github.com/danteay/golog/levels v0.1.0/go.mod h1:eWSbOC3D2TEvsl/Ngmyh1NngmX9ZNnywPTa5kVpN8Ew= +github.com/danteay/golog/levels v0.1.1 h1:cG6KT6bdmfZ7I6Q4TKGtQu+/SK2SY9FJTYzC6JBjzZo= +github.com/danteay/golog/levels v0.1.1/go.mod h1:eWSbOC3D2TEvsl/Ngmyh1NngmX9ZNnywPTa5kVpN8Ew= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= diff --git a/adapters/zerolog/options.go b/adapters/zerolog/options.go index 2141839..d85fcd5 100644 --- a/adapters/zerolog/options.go +++ b/adapters/zerolog/options.go @@ -3,16 +3,14 @@ package zerolog import ( "io" - "github.com/rs/zerolog" - "github.com/danteay/golog/levels" ) type options struct { - level levels.Level - writer io.Writer - colored bool - logger *zerolog.Logger + level levels.Level + writer io.Writer + colored bool + withTrace bool } // Option defines the signature for the options. @@ -39,9 +37,9 @@ func Colored() Option { } } -// WithLogger sets the logger for the adapter. -func WithLogger(logger zerolog.Logger) Option { +// WithTrace sets the error trace for the logger. +func WithTrace() Option { return func(opts *options) { - opts.logger = &logger + opts.withTrace = true } } diff --git a/adapters/zerolog/options_test.go b/adapters/zerolog/options_test.go index 97086b3..6102f31 100644 --- a/adapters/zerolog/options_test.go +++ b/adapters/zerolog/options_test.go @@ -2,12 +2,8 @@ package zerolog import ( "bytes" - "os" "testing" - "github.com/rs/zerolog" - "github.com/stretchr/testify/assert" - "github.com/danteay/golog/levels" ) @@ -39,13 +35,6 @@ func TestColored(t *testing.T) { } } -func TestWithLogger(t *testing.T) { - opts := &options{} - WithLogger(zerolog.New(os.Stdout))(opts) - - assert.NotNil(t, opts.logger) -} - func TestOptionChaining(t *testing.T) { opts := &options{} WithLevel(levels.Error)(opts) diff --git a/adapters/zerolog/zerolog.go b/adapters/zerolog/zerolog.go index 0f920cd..d9a5296 100644 --- a/adapters/zerolog/zerolog.go +++ b/adapters/zerolog/zerolog.go @@ -4,6 +4,8 @@ import ( "fmt" "io" "os" + "runtime/debug" + "strings" "github.com/danteay/golog/fields" "github.com/danteay/golog/levels" @@ -12,28 +14,42 @@ import ( // Adapter is a zerolog adapter implementation type Adapter struct { - logger zerolog.Logger + logger zerolog.Logger + level levels.Level + writer io.Writer + withTrace bool } func New(opts ...Option) *Adapter { logOpts := options{ level: levels.Info, colored: false, + writer: os.Stdout, } for _, opt := range opts { opt(&logOpts) } - if logOpts.logger != nil { - return &Adapter{ - logger: *logOpts.logger, - } + adapter := &Adapter{ + level: logOpts.level, + writer: getWriter(logOpts.writer, logOpts.colored), + withTrace: logOpts.withTrace, } - return &Adapter{ - logger: getLogger(logOpts), - } + adapter.logger = getLogger(adapter.level, adapter.writer) + + return adapter +} + +// Writer returns the writer for the adapter +func (a *Adapter) Writer() io.Writer { + return a.writer +} + +// SetWriter sets the writer for the adapter +func (a *Adapter) SetWriter(w io.Writer) { + a.writer = w } // Logger returns the zerolog logger instance @@ -45,9 +61,7 @@ func (a *Adapter) Logger() zerolog.Logger { func (a *Adapter) Log(level levels.Level, err error, logFields *fields.Fields, msg string, args ...any) { log := a.getLog(level) - if err != nil { - log = log.Err(err) - } + addErrFields(level, err, log, a.withTrace) if logFields != nil { for k, v := range logFields.Data() { @@ -76,14 +90,34 @@ func (a *Adapter) getLog(level levels.Level) *zerolog.Event { return event() } +func addErrFields(level levels.Level, err error, evt *zerolog.Event, withTrace bool) { + if err == nil { + return + } + + evt.Err(err) + + if withTrace || level == levels.TraceLevel { + evt.Interface("stack", getStackTrace()) + } +} + +func getStackTrace() []string { + stack := strings.ReplaceAll(string(debug.Stack()), "\t", "") + return strings.Split(stack, "\n") +} + func getLevels(level levels.Level) zerolog.Level { levelList := map[levels.Level]zerolog.Level{ - levels.Debug: zerolog.DebugLevel, - levels.Info: zerolog.InfoLevel, - levels.Warn: zerolog.WarnLevel, - levels.Error: zerolog.ErrorLevel, - levels.Fatal: zerolog.FatalLevel, - levels.Panic: zerolog.PanicLevel, + levels.NoLevel: zerolog.NoLevel, + levels.Disabled: zerolog.Disabled, + levels.TraceLevel: zerolog.TraceLevel, + levels.Debug: zerolog.DebugLevel, + levels.Info: zerolog.InfoLevel, + levels.Warn: zerolog.WarnLevel, + levels.Error: zerolog.ErrorLevel, + levels.Fatal: zerolog.FatalLevel, + levels.Panic: zerolog.PanicLevel, } zl, exists := levelList[level] @@ -94,16 +128,17 @@ func getLevels(level levels.Level) zerolog.Level { return zl } -func getLogger(opts options) zerolog.Logger { - var writer io.Writer = os.Stdout - - if opts.colored { - writer = zerolog.ConsoleWriter{Out: os.Stdout} +func getWriter(baseWriter io.Writer, colored bool) io.Writer { + if colored { + return zerolog.ConsoleWriter{Out: baseWriter} } - if opts.writer != nil { - writer = opts.writer - } + return baseWriter +} - return zerolog.New(writer).With().Timestamp().Logger().Level(getLevels(opts.level)) +func getLogger(level levels.Level, writer io.Writer) zerolog.Logger { + return zerolog.New(writer). + With().Timestamp(). + Logger(). + Level(getLevels(level)) }