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

标签 go

作为学习练习,我着手编写一个简单的包装器来包装 "go.uber.org/zap",并可能在每次我的日志记录功能运行时添加一些指标 (statsD)呼吁让这变得有值(value)。

.Info 实现按预期工作。

有趣的是,.Infow 不起作用。我似乎无法让它为 ...interface{} 类型工作,并且出现错误:

2019-08-09T23:46:27.250-0400    DPANIC  zap/sugar.go:179    Ignored key without a value.    {"ignored": [{},{}]}

完全实现:

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

如何正确传递 ...interface{} 到 zap?

源文档:

article1 article2

最佳答案

魔鬼在于细节。如 docs 中所述,以下是正确的:

func (l *logger) Infow(msg string, keysAndValues ...interface{}) {
    l.zapInstance.Infow(msg, keysAndValues...)
}

关于go - GO 中的工厂模式(包装器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57439164/

相关文章:

file - 如何在 Go 中的 io.Reader 上测试 EOF?

Go编译器技巧

go - 有没有一种断言类型的通用方法?

sql - 是否可以从 sql.Rows 获取 SQL 查询字符串?

json - 我该怎么做呢?将结构作为接口(interface)发送到函数并将其作为结构取回?

arrays - 如何设置字节数组的位

go - 如何从反向代理获取响应头

linux - 有什么有效的方法可以轻松获取Unix下Go程序的panic log吗?

function - 为什么我可以从Go中的类型调用func?

go - 减少多路复用中间件和自定义上下文实现中的样板