Home

Awesome

Zax (zap with context)

codecov CodeQL Check & Build License: AGPL v3 GitHub release (latest SemVer) Go Report Card

Zax is a library that adds context to Zap Logger and makes it easier for Gophers to avoid generating logger boilerplates. By passing the logger as a parameter to functions, it enhances parameter functionality and avoids the need for multiple methods with explicit dependencies.

Installation

  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, []zap.Field{zap.String("trace_id", "my-trace-id")})

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")

To retrieve an specific field in the context you can use zax.GetField:

 zax.GetField(ctx, "trace_id")

After that, you can use the output as a regular logger and perform logging operations:

logger.With(zax.Get(ctx)...).Info("message")
logger.With(zax.Get(ctx)...).Debug("message")
example:

Let's say you want to generate a tracer at the entry point of your system and keep it until the process finishes:

func main() {
    logger, _ := zap.NewProduction()
    ctx := context.Background()
    s := NewServiceA(logger)
    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, []zap.Field{zap.String("trace_id", "my-trace-id"),zap.String("span_id", "my-span-id")})
    s.funcA(ctx)
}

type ServiceA struct {
logger *zap.Logger
}

func NewServiceA(logger *zap.Logger) *ServiceA {
    return &ServiceA{
        logger: logger,
    }
}

func (s *ServiceA) funcA(ctx context.Context) {
    s.logger.Info("func A") // it does not contain trace_id, you need to add it manually
	s.logger.With(zax.Get(ctx)...).Info("func A") // it will logged with "trace_id" = "my-trace-id"
}

benchmark

We have benchmarked Zax V2,V1 and Zap using the same fields. Here are the benchmark results: As you can see in V2 (Method with storing only fields in context, has better performance than V1 ( storing the whole logger object in context))

pkg: github.com/yuseferi/zax/v2
BenchmarkLoggingWithOnlyZap-10          103801226               35.56 ns/op          112 B/op          1 allocs/op
BenchmarkLoggingWithOnlyZap-10          98576570                35.56 ns/op          112 B/op          1 allocs/op
BenchmarkLoggingWithOnlyZap-10          100000000               35.24 ns/op          112 B/op          1 allocs/op
BenchmarkLoggingWithOnlyZap-10          100000000               34.85 ns/op          112 B/op          1 allocs/op
BenchmarkLoggingWithOnlyZap-10          100000000               34.98 ns/op          112 B/op          1 allocs/op
BenchmarkLoggingWithZaxV2-10            64324434                56.02 ns/op           72 B/op          2 allocs/op
BenchmarkLoggingWithZaxV2-10            63939517                56.98 ns/op           72 B/op          2 allocs/op
BenchmarkLoggingWithZaxV2-10            63374052                57.60 ns/op           72 B/op          2 allocs/op
BenchmarkLoggingWithZaxV2-10            63417358                57.37 ns/op           72 B/op          2 allocs/op
BenchmarkLoggingWithZaxV2-10            57964246                57.97 ns/op           72 B/op          2 allocs/op
BenchmarkLoggingWithZaxV1-10            54062712                66.40 ns/op          160 B/op          2 allocs/op
BenchmarkLoggingWithZaxV1-10            53155524                65.61 ns/op          160 B/op          2 allocs/op
BenchmarkLoggingWithZaxV1-10            54428521                64.19 ns/op          160 B/op          2 allocs/op
BenchmarkLoggingWithZaxV1-10            55420744                64.28 ns/op          160 B/op          2 allocs/op
BenchmarkLoggingWithZaxV1-10            55199061                64.50 ns/op          160 B/op          2 allocs/op
PASS
ok      github.com/yuseferi/zax/v2      56.919s


Contributing

We strongly believe in open-source ❤️😊. Please feel free to contribute by raising issues and submitting pull requests to make Zax even better!

Released under the GNU GENERAL PUBLIC LICENSE.