如何标准化 go-kit/kit/log 的字段?

huangapple go评论75阅读模式
英文:

How to standardize go-kit/kit/log fields

问题

问题

go-kit/log的日志记录接口非常简单明了:

type Logger interface {
    Log(keyvals ...interface{}) error
}

但是人们往往以不同的方式思考,并用不同的名称来称呼相同的事物。

我在代码中看到有人将错误文本字段称为"err",而其他人称为"error"。这使得日志难以搜索。你必须同时搜索"err"和"error"。这也可能发生在"msg"或"message"字段上。

有没有办法标准化这样的命名?

英文:

Problem

go-kit/log Logging interface is straightforward and nice

type Logger interface {
    Log(keyvals ...interface{}) error
}

But people tend to think in different ways and name the same things with different names.

I see in a code that one calls a field for error text as "err" and other "error". This makes logs difficult to search for. You have to search for both "err" and "error" in the same time. This also can be the case for "msg" or "message" fields.

Is there any way to standardize such naming?

答案1

得分: 3

我会为你翻译以下内容:

我发现建造者模式更加清晰和可读:

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)
英文:

I'd find a builder pattern cleaner and more readable:

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
}

Using it:

var logger Logger

logger.Log(NewKVBuilder().
	Err(errors.New("foo")).
	Msg("bar").
	KV("some", "other").
	KeyVals...,
)

And if you add another method to KVBuilder:

func (k *KVBuilder) LogTo(logger Logger) error {
	return logger.Log(k.KeyVals...)
}

You can also use it like this:

NewKVBuilder().
	Err(errors.New("foo")).
	Msg("bar").
	KV("some", "other").
	LogTo(logger)

答案2

得分: 2

我看到解决这个问题的三个选项:
1)团队内部的正式约定和一个代码检查工具(linter)来检查它。
2)使用共享的标记包来声明日志字段名称为常量(例如opentracing-go中的示例扩展包)。团队始终使用Log(ext.Message, "log message text", ext.Error, err)这样的调用。
3)一种语法糖,它隐藏了字段命名的细节。它可以像这样实现(live example):

// 包 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
}

// 使用示例

// 包 main
import lh "./loghelper"
cid := "42"
logger.Log(lh.KV(
  lh.Msg("log message text"), 
  lh.Err(errors.New("error-test")), 
  "customer.id", cid
)...)
英文:

I see three options to solve this problem:

  1. A formal convention within a team and a linter to check it
  2. A shared tagging package for log field names declared as consts (example ext package in opentracing-go). A team always use it for Log(ext.Message, "log message text", ext.Error, err) calls.
  3. A syntactic sugar which hides the field naming inside. It can look like this (live example)
    // 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
    )...)

huangapple
  • 本文由 发表于 2021年10月19日 15:48:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/69626906.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定