diff --git a/README.md b/README.md index ce21e44..fe2e908 100644 --- a/README.md +++ b/README.md @@ -11,24 +11,28 @@ Zax is a library that adds context to [Zap Logger](https://github.com/uber-go/za ### Installation ```shell - go get -u github.com/yuseferi/zax + go get -u github.com/yuseferi/zax/v2 ``` ### Usage: To add something to the context and carry it along, simply use zap.Set: - ctx = zax.Set(ctx, logger, zap.String("trace_id", "my-trace-id")) + ctx = zax.Set(ctx, []zap.Field{zap.String("trace_id", "my-trace-id")}) -To retrieve a logger with the contexted fields, use zax.Get: +To retrieve stored zap fields in context, use zax.Get: + + zax.Get(ctx) // this retrive stored zap fields in context + +To retrieve stored zap fields in context and log them : + + logger.With(zax.Get(ctx)...).Info("just a test record") - zax.Get(ctx) After that, you can use the output as a regular logger and perform logging operations: ```Go -zax.Get(ctx).Info(....) -zax.Get(ctx).Debug(....) -..... +logger.With(zax.Get(ctx)...).Info("message") +logger.With(zax.Get(ctx)...).Debug("message") ``` @@ -41,9 +45,9 @@ func main() { logger, _ := zap.NewProduction() ctx := context.Background() s := NewServiceA(logger) - ctx = zax.Set(ctx, logger, zap.String("trace_id", "my-trace-id")) + ctx = zax.Set(ctx, zap.String("trace_id", "my-trace-id")) // and if you want to add multiple of them at once - //ctx = zax.Set(ctx, logger, []zap.Field{zap.String("trace_id", "my-trace-id"),zap.String("span_id", "my-span-id")}) + //ctx = zax.Set(ctx, []zap.Field{zap.String("trace_id", "my-trace-id"),zap.String("span_id", "my-span-id")}) s.funcA(ctx) } @@ -59,7 +63,7 @@ func NewServiceA(logger *zap.Logger) *ServiceA { func (s *ServiceA) funcA(ctx context.Context) { s.logger.Info("func A") // it does not contain trace_id, you need to add it manually - zax.Get(ctx).Info("func A") // it will logged with "trace_id" = "my-trace-id" + s.logger.With(zax.Get(ctx)...).Info("func A") // it will logged with "trace_id" = "my-trace-id" } ``` @@ -67,16 +71,18 @@ func (s *ServiceA) funcA(ctx context.Context) { We have benchmarked Zax against Zap using the same fields. Here are the benchmark results: ``` -BenchmarkLoggingWithOnlyZap-10 31756287 34.97 ns/op -BenchmarkLoggingWithOnlyZap-10 35056582 35.06 ns/op -BenchmarkLoggingWithOnlyZap-10 32982284 35.90 ns/op -BenchmarkLoggingWithOnlyZap-10 35061405 34.95 ns/op -BenchmarkLoggingWithOnlyZap-10 33266068 34.86 ns/op -BenchmarkLoggingWithZax-10 18442729 64.53 ns/op -BenchmarkLoggingWithZax-10 18592747 65.57 ns/op -BenchmarkLoggingWithZax-10 17492030 65.26 ns/op -BenchmarkLoggingWithZax-10 18640606 64.66 ns/op -BenchmarkLoggingWithZax-10 18700837 64.58 ns/op +pkg: github.com/yuseferi/zax/v2 +BenchmarkLoggingWithOnlyZap-10 344718321 35.23 ns/op +BenchmarkLoggingWithOnlyZap-10 340526908 36.74 ns/op +BenchmarkLoggingWithOnlyZap-10 337279976 36.17 ns/op +BenchmarkLoggingWithOnlyZap-10 338681052 36.18 ns/op +BenchmarkLoggingWithOnlyZap-10 339414484 35.48 ns/op +BenchmarkLoggingWithZax-10 201602071 56.58 ns/op +BenchmarkLoggingWithZax-10 213688218 57.44 ns/op +BenchmarkLoggingWithZax-10 206059045 56.66 ns/op +BenchmarkLoggingWithZax-10 211847756 58.14 ns/op +BenchmarkLoggingWithZax-10 210184916 56.69 ns/op + ``` ### Contributing diff --git a/go.mod b/go.mod index 8bd9dbe..7c9ae79 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/yuseferi/zax +module github.com/yuseferi/zax/v2 go 1.21 @@ -10,6 +10,6 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 27db194..947ad7c 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/zax.go b/zax.go index 350a934..7c430e6 100644 --- a/zax.go +++ b/zax.go @@ -4,26 +4,24 @@ package zax import ( "context" + "go.uber.org/zap" ) type Key string -// Key name which used for save logger in context +// Key name which used for save fields in context const loggerKey = Key("zax") -// Set Add passed fields to logger and store zap.Logger as variable in context -func Set(ctx context.Context, logger *zap.Logger, fields []zap.Field) context.Context { - if len(fields) > 0 { - logger = logger.With(fields...) - } - return context.WithValue(ctx, loggerKey, logger) +// Set Add passed fields in context +func Set(ctx context.Context, fields []zap.Field) context.Context { + return context.WithValue(ctx, loggerKey, fields) } -// Get zap.Logger from context -func Get(ctx context.Context) *zap.Logger { - if logger, ok := ctx.Value(loggerKey).(*zap.Logger); ok { - return logger +// Get zap stored fields from context +func Get(ctx context.Context) []zap.Field { + if loggerFields, ok := ctx.Value(loggerKey).([]zap.Field); ok { + return loggerFields } - return zap.L() + return nil } diff --git a/zax_benchmark_test.go b/zax_benchmark_test.go index c15bc50..25d3e82 100644 --- a/zax_benchmark_test.go +++ b/zax_benchmark_test.go @@ -2,9 +2,10 @@ package zax import ( "context" + "testing" + "go.uber.org/zap" "go.uber.org/zap/zapcore" - "testing" ) var someFields = []zap.Field{ @@ -19,8 +20,8 @@ func LogWithZap(logger *zap.Logger) { func LogWithZax(logger *zap.Logger) { ctx := context.Background() - Set(ctx, logger, someFields) - Get(ctx).Info("logging something") + Set(ctx, someFields) + logger.With(Get(ctx)...).Info("logging something") } func BenchmarkLoggingWithOnlyZap(b *testing.B) { diff --git a/zax_test.go b/zax_test.go index 69df6b3..138931c 100644 --- a/zax_test.go +++ b/zax_test.go @@ -43,6 +43,9 @@ func (l *Logger) AssertLogEntryExist(t assert.TestingT, key, value string) bool } } } + if key == "" && value == "" { + return true + } return assert.Fail(t, fmt.Sprintf("log entry does not exist with, %s = %s", key, value)) } @@ -69,13 +72,18 @@ func TestSet(t *testing.T) { expectedLoggerKey string expectedLoggerValue string }{ + "context for zax filed is empty": { + context: Set(ctx, nil), + expectedLoggerKey: "", + expectedLoggerValue: "", + }, "context with trace-id": { - context: Set(ctx, testLog.logger, []zap.Field{zap.String(traceIDKey, testTraceID)}), + context: Set(ctx, []zap.Field{zap.String(traceIDKey, testTraceID)}), expectedLoggerKey: traceIDKey, expectedLoggerValue: testTraceID, }, "context with trace-id with new value(to check it will be updated)": { - context: Set(ctx, testLog.logger, []zap.Field{zap.String(traceIDKey, testTraceID2)}), + context: Set(ctx, []zap.Field{zap.String(traceIDKey, testTraceID2)}), expectedLoggerKey: traceIDKey, expectedLoggerValue: testTraceID2, }, @@ -84,7 +92,7 @@ func TestSet(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { ctx := tc.context - logger := ctx.Value(loggerKey).(*zap.Logger) + logger := testLog.logger.With(Get(ctx)...) logger.Info("just a test record") assert.NotNil(t, logger) testLog.AssertLogEntryExist(t, tc.expectedLoggerKey, tc.expectedLoggerValue) @@ -101,12 +109,12 @@ func TestGet(t *testing.T) { context context.Context expectedLoggerKey *string }{ - "context with trace-id": { + "context empty": { context: context.TODO(), expectedLoggerKey: nil, }, - "context with trace-id with new value(to check it will be updated)": { - context: Set(ctx, testLog.logger, []zap.Field{zap.String(traceIDKey, testTraceID)}), + "context with trace-id field": { + context: Set(ctx, []zap.Field{zap.String(traceIDKey, testTraceID)}), expectedLoggerKey: &traceIDKey, }, } @@ -114,7 +122,7 @@ func TestGet(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { ctx := tc.context - Get(ctx).Info("just a test record") + testLog.logger.With(Get(ctx)...).Info("just a test record") if tc.expectedLoggerKey != nil { testLog.AssertLogEntryKeyExist(t, *tc.expectedLoggerKey) }