diff --git a/CHANGELOG.md b/CHANGELOG.md index 0324e49..d071bbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ Changelog for ecszap ## unreleased +### Enhancement +* Add `ecszap.WrapCoreOption` for convenience [pull#22](https://github.com/elastic/ecs-logging-go-zap/pull/22) + ### Bug Fixes * Change `stacktrace` to `stack_trace` in output and in json and yaml config option for `EncoderConfig.EnableStacktrace` [pull#21](https://github.com/elastic/ecs-logging-go-zap/pull/21) @@ -24,4 +27,4 @@ Changelog for ecszap * remove `ecszap.NewJSONEncoder` [pull#12](https://github.com/elastic/ecs-logging-go-zap/pull/12) ## 0.1.0 -Initial Pre-Release supporting [MVP](https://github.com/elastic/ecs-logging/tree/master/spec#minimum-viable-product) for ECS conformant logging \ No newline at end of file +Initial Pre-Release supporting [MVP](https://github.com/elastic/ecs-logging/tree/master/spec#minimum-viable-product) for ECS conformant logging diff --git a/README.md b/README.md index 399a6a3..172736e 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,8 @@ logger := zap.New(core, zap.AddCaller()) ``` ### Transition from existing configurations +Depending on your needs there are different ways how to create the logger: + ```go encoderConfig := ecszap.ECSCompatibleEncoderConfig(zap.NewDevelopmentEncoderConfig()) encoder := zapcore.NewJSONEncoder(encoderConfig) @@ -138,6 +140,13 @@ core := zapcore.NewCore(encoder, os.Stdout, zap.DebugLevel) logger := zap.New(ecszap.WrapCore(core), zap.AddCaller()) ``` +```go +config := zap.NewProductionConfig() +config.EncoderConfig = ecszap.ECSCompatibleEncoderConfig(config.EncoderConfig) +logger, err := config.Build(ecszap.WrapCoreOption(), zap.AddCaller()) +``` + + ## References * Introduction to ECS [blog post](https://www.elastic.co/blog/introducing-the-elastic-common-schema). * Logs UI [blog post](https://www.elastic.co/blog/infrastructure-and-logs-ui-new-ways-for-ops-to-interact-with-elasticsearch). diff --git a/core.go b/core.go index 618c6fb..4a6aec7 100644 --- a/core.go +++ b/core.go @@ -33,14 +33,19 @@ func NewCore(cfg EncoderConfig, ws zapcore.WriteSyncer, enab zapcore.LevelEnable return WrapCore(zapcore.NewCore(enc, ws, enab)) } -// WrapCore wraps a given core with ECS core functionality. For ECS -// compatibility, ensure that the wrapped zapcore.Core uses an encoder +// WrapCore wraps a core with ECS core functionality and returns a zapcore.Core. +// For ECS compatibility, ensure that the wrapped zapcore.Core uses an encoder // that is created from an ECS compatible configuration. For further details // check out ecszap.EncoderConfig or ecszap.ECSCompatibleEncoderConfig. func WrapCore(c zapcore.Core) zapcore.Core { return &core{c} } +// WrapCoreOption returns a zap.Option, wrapping the underlying zapcore.Core. +func WrapCoreOption() zap.Option { + return zap.WrapCore(WrapCore) +} + type core struct { zapcore.Core } diff --git a/logger_test.go b/logger_test.go index 071415f..8183b27 100644 --- a/logger_test.go +++ b/logger_test.go @@ -24,8 +24,6 @@ import ( "go.uber.org/zap/zapcore" - errs "github.com/pkg/errors" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" @@ -61,7 +59,7 @@ func TestECSZapLogger_With(t *testing.T) { }{ {name: "newCoreFromConfig", core: NewCore(NewDefaultEncoderConfig(), &out, zap.DebugLevel)}, - {name: "", + {name: "wrappedCore", core: func() zapcore.Core { ecsEncCfg := ECSCompatibleEncoderConfig(zap.NewProductionEncoderConfig()) enc := zapcore.NewJSONEncoder(ecsEncCfg) @@ -81,17 +79,19 @@ func TestECSZapLogger_With(t *testing.T) { // log a wrapped error out.reset() - err := errors.New("boom") - logger.Error("some error", zap.Error(errs.Wrap(err, "crash"))) - out.requireContains(t, []string{"error"}) + logger.With(zap.Error(errors.New("test error"))).Error("boom") + out.requireContains(t, []string{"error", "message"}) + assert.Equal(t, "boom", out.m["message"]) + outErr, ok := out.m["error"].(map[string]interface{}) + require.True(t, ok, out.m["error"]) + assert.Equal(t, map[string]interface{}{"message": "test error"}, outErr) // Adding logger wide fields and a logger name out.reset() logger = logger.With(zap.String("foo", "bar")) - logger = logger.With(zap.Error(errors.New("wrapCore Error"))) logger = logger.Named("mylogger") logger.Debug("debug message") - out.requireContains(t, []string{"log.logger", "foo", "error"}) + out.requireContains(t, []string{"log.logger", "foo"}) // Use loosely typed logger out.reset() @@ -104,20 +104,6 @@ func TestECSZapLogger_With(t *testing.T) { "@timestamp", "log.level", "log.origin", "foo", "count"}) out.reset() - }) } - // Wrapped logger - out.reset() - cfg := ECSCompatibleEncoderConfig(zap.NewProductionEncoderConfig()) - encoder := zapcore.NewJSONEncoder(cfg) - core := zapcore.NewCore(encoder, &out, zap.DebugLevel) - logger := zap.New(WrapCore(core), zap.AddCaller()) - defer logger.Sync() - logger.With(zap.Error(errors.New("wrapCore"))).Error("boom") - out.requireContains(t, []string{"error", "message"}) - assert.Equal(t, "boom", out.m["message"]) - outErr, ok := out.m["error"].(map[string]interface{}) - require.True(t, ok, out.m["error"]) - assert.Equal(t, map[string]interface{}{"message": "wrapCore"}, outErr) }