/ecs-logging-go-zap

Logging encoder for ECS compatible logs using uber-go/zap

Primary LanguageGoApache License 2.0Apache-2.0

Elastic Common Schema (ECS) support for uber-go/zap logger

Use this library for automatically adding a minimal set of ECS fields to your logs, when using uber-go/zap.


Please note that this library is in a beta version and backwards-incompatible changes might be introduced in future releases. While we strive to comply to semver, we can not guarantee to avoid breaking changes in minor releases.


The encoder logs in JSON format, relying on the default zapcore/json_encoder when possible.

Following fields will be added by default:

{
    "log.level":"info",
    "@timestamp":1583748236254129,
    "message":"some logging info",
    "ecs.version":"1.6.0"
}

It also takes care of logging error fields in ECS error format.

What is ECS?

Elastic Common Schema (ECS) defines a common set of fields for ingesting data into Elasticsearch. For more information about ECS, visit the ECS Reference Documentation.

Installation

Add the package to your go.mod file

require go.elastic.co/ecszap master

Example usage

Set up default logger

encoderConfig := ecszap.NewDefaultEncoderConfig()
core := ecszap.NewCore(encoderConfig, os.Stdout, zap.DebugLevel)
logger := zap.New(core, zap.AddCaller())

Use structured logging

// Adding fields and a logger name
logger = logger.With(zap.String("custom", "foo"))
logger = logger.Named("mylogger")

// Use strongly typed Field values
logger.Info("some logging info",
    zap.Int("count", 17),
    zap.Error(errors.New("boom")),
}

	// Log Output:
	//{
	//	"log.level":"info",
	//	"@timestamp":1584716847523456,
	//	"log.logger":"mylogger",
	//	"log.origin":{
	//		"file.name":"main/main.go",
	//		"file.line":265
	//	},
	//	"message":"some logging info",
	//	"ecs.version":"1.6.0",
	//	"custom":"foo",
	//	"count":17,
	//	"error":{
	//		"message":"boom"
	//	}
	//}

Log errors

err := errors.New("boom")
logger.Error("some error", zap.Error(pkgerrors.Wrap(err, "crash")))

	// Log Output:
	//{
	//	"log.level":"error",
	//	"@timestamp":1584716847523842,
	//	"log.logger":"mylogger",
	//	"log.origin":{
	//		"file.name":"main/main.go",
	//		"file.line":290
	//	},
	//	"message":"some error",
	//	"ecs.version":"1.6.0",
	//	"custom":"foo",
	//	"error":{
	//		"message":"crash: boom",
	//		"stacktrace": "\nexample.example\n\t/Users/xyz/example/example.go:50\nruntime.example\n\t/Users/xyz/.gvm/versions/go1.13.8.darwin.amd64/src/runtime/proc.go:203\nruntime.goexit\n\t/Users/xyz/.gvm/versions/go1.13.8.darwin.amd64/src/runtime/asm_amd64.s:1357"
	//	}
	//}

Use sugar logger

sugar := logger.Sugar()
sugar.Infow("some logging info",
    "foo", "bar",
    "count", 17,
)

	// Log Output:
	//{
	//	"log.level":"info",
	//	"@timestamp":1584716847523941,
	//	"log.logger":"mylogger",
	//	"log.origin":{
	//		"file.name":"main/main.go",
	//		"file.line":311
	//	},
	//	"message":"some logging info",
	//	"ecs.version":"1.6.0",
	//	"custom":"foo",
	//	"foo":"bar",
	//	"count":17
	//}

Wrap a custom underlying zapcore.Core

encoderConfig := ecszap.NewDefaultEncoderConfig()
encoder := zapcore.NewJSONEncoder(encoderConfig.ToZapCoreEncoderConfig())
syslogCore := newSyslogCore(encoder, level) //create your own loggers
core := ecszap.WrapCore(syslogCore)
logger := zap.New(core, zap.AddCaller())

Transition from existing configurations

encoderConfig := ecszap.ECSCompatibleEncoderConfig(zap.NewDevelopmentEncoderConfig())
encoder := zapcore.NewJSONEncoder(encoderConfig)
core := zapcore.NewCore(encoder, os.Stdout, zap.DebugLevel)
logger := zap.New(ecszap.WrapCore(core), zap.AddCaller())

References

Test

go test ./...

Contribute

Create a Pull Request from your own fork.

Run mage to update and format you changes before submitting.

Add new dependencies to the NOTICE.txt.

License

This software is licensed under the Apache 2 license.