Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add version as service context #39

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
vendor/
.idea
18 changes: 14 additions & 4 deletions core.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -216,15 +226,15 @@ 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 {
return fields
}
}

return append(fields, ServiceContext(name))
return append(fields, ServiceContext(name, version))
}

func (c *core) withErrorReport(ent zapcore.Entry, fields []zapcore.Field) []zapcore.Field {
Expand Down
8 changes: 5 additions & 3 deletions core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -320,6 +320,7 @@ func TestWriteReportAllErrors_WithServiceContext(t *testing.T) {
config: driverConfig{
ReportAllErrors: true,
ServiceName: "test service",
ServiceVersion: "1.0.0",
},
})

Expand All @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -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
Expand Down
11 changes: 8 additions & 3 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
6 changes: 4 additions & 2 deletions service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}