As a learning exercise, I set out to write a simple wrapper to wrap "go.uber.org/zap"
, and maybe add some metrics (statsD) to each time my logging function is called to make this worthwhile.
The .Info
implementation works as expected.
What is interesting, .Infow
does not work. I can not seem to get this to work for ...interface{}
types, and am getting the error:
2019-08-09T23:46:27.250-0400 DPANIC zap/sugar.go:179 Ignored key without a value. {"ignored": [{},{}]}
Full Implementation:
package ilogger
import (
"reflect"
"go.uber.org/zap"
)
type Logger interface {
NewLogger(env string) logger
}
type logger struct {
zapInstance zap.SugaredLogger
}
func NewLogger(env string) *logger {
z := NewZapLogger(env)
return &logger{
zapInstance: *z,
}
}
func NewZapLogger(env string) *zap.SugaredLogger {
var zapInstance *zap.Logger
if env == "production" {
zapInstance, _ = zap.NewProduction()
} else {
zapInstance, _ = zap.NewDevelopment()
}
defer zapInstance.Sync() // flushes buffer, if any
return zapInstance.Sugar()
}
// Info uses fmt.Sprint to construct and log a message.
func (l *logger) Info(args ...interface{}) {
l.zapInstance.Info(args)
}
// Infow logs a message with some additional context. The variadic key-value
// pairs are treated as they are in With.
func (l *logger) Infow(msg string, keysAndValues ...interface{}) {
things := make([]reflect.Value, len(keysAndValues))
for k, in := range keysAndValues {
things[k] = reflect.ValueOf(in)
}
l.zapInstance.Infow(msg, things)
}
How do i pass ...interface{}
to zap properly?
Source Documentation:
The devil lies in details. As mentioned in the docs, the following is correct:
func (l *logger) Infow(msg string, keysAndValues ...interface{}) {
l.zapInstance.Infow(msg, keysAndValues...)
}