问题
go-kit/log日志记录界面简单而美观
type Logger interface {
Log(keyvals ...interface{}) error
}
但人们往往会以不同的方式思考,并用不同的名字命名相同的东西。
我在代码中看到,有人将错误文本的字段称为";错误"以及其他";错误";。这使得搜索日志变得困难。您必须同时搜索";错误"以及";错误";同时。这也可以是";msg"或";消息";字段。
有什么方法可以标准化这样的命名吗
我会找到一个更干净、更可读的构建器模式:
type KVBuilder struct {
KeyVals []interface{}
}
func NewKVBuilder() *KVBuilder {
return &KVBuilder{}
}
func (k *KVBuilder) Err(err error) *KVBuilder {
return k.KV("err", err)
}
func (k *KVBuilder) Msg(msg string) *KVBuilder {
return k.KV("msg", msg)
}
func (k *KVBuilder) KV(kv ...interface{}) *KVBuilder {
k.KeyVals = append(k.KeyVals, kv...)
return k
}
使用它:
var logger Logger
logger.Log(NewKVBuilder().
Err(errors.New("foo")).
Msg("bar").
KV("some", "other").
KeyVals...,
)
如果您在KVBuilder
:中添加另一种方法
func (k *KVBuilder) LogTo(logger Logger) error {
return logger.Log(k.KeyVals...)
}
你也可以这样使用它:
NewKVBuilder().
Err(errors.New("foo")).
Msg("bar").
KV("some", "other").
LogTo(logger)
我看到了解决这个问题的三个选项:
- 团队内部的正式会议,并由linter进行检查
- 用于声明为consts的日志字段名称的共享标记包(opentraceing-go中的示例ext包)。一个团队总是将其用于
Log(ext.Message, "log message text", ext.Error, err)
调用 - 一种语法糖,它将字段命名隐藏在里面。它可以是这样的(示例)
// pakage loghelper
func Err(err error) []interface{} {
return []interface{}{"err", err}
}
func Msg(s string) []interface{} {
return []interface{}{"msg", s}
}
func KV(items ...interface{}) []interface{} {
var kv []interface{}
for _, item := range items {
switch v := item.(type) {
default:
kv = append(kv, v)
case []interface{}:
kv = append(kv, v...)
}
}
return kv
}
// USAGE
// package main
import lh ./loghelper
cid = "42"
logger.Log(lh.KV(
lh.Msg("log message text"),
lh.Err(errors.New("error-test")),
"customer.id", cid
)...)