# #go #logging #naming-conventions
Вопрос:
Проблема
интерфейс ведения журнала go-kit/log прост и приятен
type Logger interface {
Log(keyvals ...interface{}) error
}
Но люди склонны думать по-разному и называть одни и те же вещи разными именами.
Я вижу в коде, что одно поле для текста ошибки называется «ошибка», а другое «ошибка». Это затрудняет поиск журналов. Вы должны искать как «ошибку», так и «ошибку» одновременно. Это также может иметь место для полей «msg» или «сообщение».
Есть ли какой-либо способ стандартизировать такое именование?
Ответ №1:
Я вижу три варианта решения этой проблемы:
- Официальное соглашение внутри команды и линтер для его проверки
- Общий пакет тегов для имен полей журнала, объявленных как const (пример пакета ext в opentracing-go). Команда всегда использует его для
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
)...)
Ответ №2:
Я бы нашел шаблон конструктора более чистым и читаемым:
type KVBuilder struct {
KeyVals []interface{}
}
func NewKVBuilder() *KVBuilder {
return amp;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)
Комментарии:
1. Хороший вариант. Спасибо, что поделились!