GO(包装器)中的工厂模式

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:

article1 article2

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...)
}