diff --git a/log/CHANGELOG.md b/log/CHANGELOG.md index 08768555e7..825178f18f 100644 --- a/log/CHANGELOG.md +++ b/log/CHANGELOG.md @@ -31,9 +31,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] -### Features +* [#15956](https://github.com/cosmos/cosmos-sdk/pull/15956) Introduce an option for enabling error stack trace. -* [#15956](https://github.com/cosmos/cosmos-sdk/pull/15956) Introduce extra options to configure logger. +## [v1.1.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.1.0) - 2023-04-27 + +* [#15956](https://github.com/cosmos/cosmos-sdk/pull/15956) Introduce options to configure logger (enable/disable colored output, customize log timestamps). ## [v1.0.0](https://github.com/cosmos/cosmos-sdk/releases/tag/log/v1.0.0) - 2023-03-30 diff --git a/log/go.mod b/log/go.mod index 669a27a9de..d95055b2b4 100644 --- a/log/go.mod +++ b/log/go.mod @@ -3,6 +3,7 @@ module cosmossdk.io/log go 1.20 require ( + github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.29.1 gotest.tools/v3 v3.5.0 ) diff --git a/log/go.sum b/log/go.sum index 0a65afbd40..4676af0b69 100644 --- a/log/go.sum +++ b/log/go.sum @@ -9,6 +9,7 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= diff --git a/log/logger.go b/log/logger.go index 46ae75b619..c6a86e18ba 100644 --- a/log/logger.go +++ b/log/logger.go @@ -3,7 +3,9 @@ package log import ( "io" + "github.com/pkg/errors" "github.com/rs/zerolog" + "github.com/rs/zerolog/pkgerrors" ) // ModuleKey defines a module logging key. @@ -69,6 +71,14 @@ func NewLogger(dst io.Writer, options ...Option) Logger { } logger := zerolog.New(output) + if logCfg.StackTrace { + zerolog.ErrorStackMarshaler = func(err error) interface{} { + return pkgerrors.MarshalStack(errors.WithStack(err)) + } + + logger = logger.With().Stack().Logger() + } + if logCfg.TimeFormat != "" { logger = logger.With().Timestamp().Logger() } diff --git a/log/logger_test.go b/log/logger_test.go new file mode 100644 index 0000000000..95f3fb76f8 --- /dev/null +++ b/log/logger_test.go @@ -0,0 +1,32 @@ +package log_test + +import ( + "bytes" + "errors" + "strings" + "testing" + + "cosmossdk.io/log" +) + +func TestLoggerOptionStackTrace(t *testing.T) { + t.Skip() // todo(@julienrbrt) unskip when https://github.com/rs/zerolog/pull/560 merged + + buf := new(bytes.Buffer) + logger := log.NewLogger(buf, log.TraceOption(true), log.ColorOption(false)) + logger.Error("this log should be displayed", "error", inner()) + if strings.Count(buf.String(), "logger_test.go") != 1 { + t.Fatalf("stack trace not found, got: %s", buf.String()) + } + buf.Reset() + + logger = log.NewLogger(buf, log.TraceOption(false), log.ColorOption(false)) + logger.Error("this log should be displayed", "error", inner()) + if strings.Count(buf.String(), "logger_test.go") > 0 { + t.Fatalf("stack trace found, got: %s", buf.String()) + } +} + +func inner() error { + return errors.New("seems we have an error here") +} diff --git a/log/options.go b/log/options.go index f939fd4863..22a1eb2284 100644 --- a/log/options.go +++ b/log/options.go @@ -12,6 +12,7 @@ var defaultConfig = Config{ Filter: nil, OutputJSON: false, Color: true, + StackTrace: false, TimeFormat: time.Kitchen, } @@ -21,6 +22,7 @@ type Config struct { Filter FilterFunc OutputJSON bool Color bool + StackTrace bool TimeFormat string } @@ -78,3 +80,10 @@ func TimeFormatOption(format string) Option { cfg.TimeFormat = format } } + +// TraceOption add option to enable/disable print of stacktrace on error log +func TraceOption(val bool) Option { + return func(cfg *Config) { + cfg.StackTrace = val + } +}