diff --git a/.gitignore b/.gitignore index 48b8bf9..31e3ac6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vendor/ +.idea diff --git a/core.go b/core.go index bcb7660..f3b9af6 100644 --- a/core.go +++ b/core.go @@ -15,6 +15,8 @@ type driverConfig struct { // ServiceName is added as `ServiceContext()` to all logs when set ServiceName string + // ServiceVersion is added as `ServiceContext()` to all logs when set + ServiceVersion string } // Core is a zapdriver specific core wrapped around the default zap core. It @@ -58,6 +60,14 @@ func ServiceName(name string) func(*core) { } } +// zapdriver core option to add `ServiceContext()` to all logs with `version` as +// service version +func ServiceVersion(version string) func(*core) { + return func(c *core) { + c.config.ServiceVersion = version + } +} + // WrapCore returns a `zap.Option` that wraps the default core with the // zapdriver one. func WrapCore(options ...func(*core)) zap.Option { @@ -124,14 +134,14 @@ func (c *core) Write(ent zapcore.Entry, fields []zapcore.Field) error { fields = append(fields, labelsField(c.allLabels())) fields = c.withSourceLocation(ent, fields) if c.config.ServiceName != "" { - fields = c.withServiceContext(c.config.ServiceName, fields) + fields = c.withServiceContext(c.config.ServiceName, c.config.ServiceVersion, fields) } if c.config.ReportAllErrors && zapcore.ErrorLevel.Enabled(ent.Level) { fields = c.withErrorReport(ent, fields) if c.config.ServiceName == "" { // A service name was not set but error report needs it // So attempt to add a generic service name - fields = c.withServiceContext("unknown", fields) + fields = c.withServiceContext("unknown", "", fields) } } @@ -216,7 +226,7 @@ func (c *core) withSourceLocation(ent zapcore.Entry, fields []zapcore.Field) []z return append(fields, SourceLocation(ent.Caller.PC, ent.Caller.File, ent.Caller.Line, true)) } -func (c *core) withServiceContext(name string, fields []zapcore.Field) []zapcore.Field { +func (c *core) withServiceContext(name, version string, fields []zapcore.Field) []zapcore.Field { // If the service context was manually set, don't overwrite it for i := range fields { if fields[i].Key == serviceContextKey { @@ -224,7 +234,7 @@ func (c *core) withServiceContext(name string, fields []zapcore.Field) []zapcore } } - return append(fields, ServiceContext(name)) + return append(fields, ServiceContext(name, version)) } func (c *core) withErrorReport(ent zapcore.Entry, fields []zapcore.Field) []zapcore.Field { diff --git a/core_test.go b/core_test.go index 85d8c3a..050cef5 100644 --- a/core_test.go +++ b/core_test.go @@ -141,10 +141,10 @@ func TestWithServiceContext(t *testing.T) { want := []zap.Field{ zap.String("hello", "world"), - zap.Object(serviceContextKey, newServiceContext("test service")), + zap.Object(serviceContextKey, newServiceContext("test service", "1.0.0")), } - assert.Equal(t, want, (&core{}).withServiceContext("test service", fields)) + assert.Equal(t, want, (&core{}).withServiceContext("test service", "1.0.0", fields)) } func TestWithServiceContext_DoesNotOverwrite(t *testing.T) { @@ -154,7 +154,7 @@ func TestWithServiceContext_DoesNotOverwrite(t *testing.T) { zap.String(serviceContextKey, "world"), } - assert.Equal(t, want, (&core{}).withServiceContext("test service", fields)) + assert.Equal(t, want, (&core{}).withServiceContext("test service", "1.0.0", fields)) } func TestWrite(t *testing.T) { @@ -320,6 +320,7 @@ func TestWriteReportAllErrors_WithServiceContext(t *testing.T) { config: driverConfig{ ReportAllErrors: true, ServiceName: "test service", + ServiceVersion: "1.0.0", }, }) @@ -335,6 +336,7 @@ func TestWriteReportAllErrors_WithServiceContext(t *testing.T) { // Assert that a service context was attached even though service name was not set serviceContext := logs.All()[0].ContextMap()[serviceContextKey].(map[string]interface{}) assert.Equal(t, "test service", serviceContext["service"]) + assert.Equal(t, "1.0.0", serviceContext["version"]) } func TestWriteReportAllErrors_InfoLog(t *testing.T) { diff --git a/go.mod b/go.mod index ba02fc0..0cf0ccf 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/blendle/zapdriver -go 1.13 +go 1.16 require ( github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/service.go b/service.go index 134ff36..53155e1 100644 --- a/service.go +++ b/service.go @@ -12,25 +12,30 @@ const serviceContextKey = "serviceContext" // // see: https://cloud.google.com/error-reporting/reference/rest/v1beta1/ServiceContext // see: https://cloud.google.com/error-reporting/docs/formatting-error-messages -func ServiceContext(name string) zap.Field { - return zap.Object(serviceContextKey, newServiceContext(name)) +func ServiceContext(name, version string) zap.Field { + return zap.Object(serviceContextKey, newServiceContext(name, version)) } // serviceContext describes a running service that sends errors. // Currently it only describes a service name. type serviceContext struct { Name string `json:"service"` + Version string `json:"version"` } // MarshalLogObject implements zapcore.ObjectMarshaller interface. func (service_context serviceContext) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("service", service_context.Name) + if service_context.Version != "" { + enc.AddString("version", service_context.Version) + } return nil } -func newServiceContext(name string) *serviceContext { +func newServiceContext(name, version string) *serviceContext { return &serviceContext{ Name: name, + Version: version, } } diff --git a/service_test.go b/service_test.go index 72b03c9..e13906c 100644 --- a/service_test.go +++ b/service_test.go @@ -9,15 +9,17 @@ import ( func TestServiceContext(t *testing.T) { t.Parallel() - got := ServiceContext("test service name").Interface.(*serviceContext) + got := ServiceContext("test service name", "1.0.0").Interface.(*serviceContext) assert.Equal(t, "test service name", got.Name) + assert.Equal(t, "1.0.0", got.Version) } func TestNewServiceContext(t *testing.T) { t.Parallel() - got := newServiceContext("test service name") + got := newServiceContext("test service name", "1.0.0") assert.Equal(t, "test service name", got.Name) + assert.Equal(t, "1.0.0", got.Version) }