Введение
Существует множество библиотек ведения журналов для каждого языка программирования, потому что ведение журналов является обязательным в каждом проекте. Ранее мы представили стандартную библиотеку ведения журналов.log
, полезныйlogrus
И высокопроизводительная библиотека ведения журналов с открытым исходным кодом от uber, представленная в предыдущей статье.zap
.zerolog
в сравнении сzap
Идя дальше, его дизайн API очень ориентирован на опыт разработки и производительность.zerolog
Сосредоточьтесь только на регистрации журналов в формате JSON, известном как 0 выделение памяти!
быстрый в использовании
Сначала установите:
$ go get github.com/rs/zerolog/log
После использования:
package main
import "github.com/rs/zerolog/log"
func main() {
log.Print("hello world")
}
Общее использование и стандартная библиотекаlog
Очень похоже, за исключением того, что выходные данные представляют собой журналы в формате JSON:
{"level":"debug","time":"2020-04-25T13:43:08+08:00","message":"hello world"}
поле
Мы можем добавить в журнал дополнительную информацию о полях, чтобы облегчить отладку и отслеживание проблем. а такжеzap
Такой же,zerolog
Также различайте типы полей, разницаzerolog
использоватьцепной вызовПуть:
func main() {
log.Debug().
Str("Scale", "833 cents").
Float64("Interval", 833.09).
Msg("Fibonacci is everywhere")
log.Debug().
Str("Name", "Tom").
Send()
}
перечислитьMsg()
илиSend()
После этого будет выведен лог:
{"level":"debug","Scale":"833 cents","Interval":833.09,"time":"2020-04-25T13:55:44+08:00","message":"Fibonacci is everywhere"}
{"level":"debug","Name":"Tom","time":"2020-04-25T13:55:44+08:00"}
вложенный
Поля записи могут быть произвольно вложены друг в друга, что достигаетсяDict()
реализовать:
func main() {
log.Info().
Dict("dict", zerolog.Dict().
Str("bar", "baz").
Int("n", 1),
).Msg("hello world")
}
выходdict
Поля являются вложенными структурами:
{"level":"info","dict":{"bar":"baz","n":1},"time":"2020-04-25T14:34:51+08:00","message":"hello world"}
ГлобальныйLogger
Выше мы используемlog.Debug()
,log.Info()
вызов глобальныйLogger
. ГлобальныйLogger
Он относительно прост в использовании и не требует дополнительного создания.
установить уровень журнала
Каждая библиотека журналов имеет концепцию уровня журнала, и разделение в основном такое же.zerolog
имеютpanic/fatal/error/warn/info/debug/trace
эти уровни. мы можем позвонитьSetGlobalLevel()
установить глобальныйLogger
уровень журнала.
func main() {
debug := flag.Bool("debug", false, "sets log level to debug")
flag.Parse()
if *debug {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
log.Debug().Msg("This message appears only when log level set to debug")
log.Info().Msg("This message appears when log level set to debug or info")
if e := log.Debug(); e.Enabled() {
e.Str("foo", "bar").Msg("some debug message")
}
}
В приведенном выше коде мы устанавливаем уровень журнала на основе входящих параметров командной строки какDebug
все ещеInfo
. Если уровень журналаInfo
,Debug
Лог не выводится. также можно назватьEnabled()
чтобы определить, нужно ли выводить журнал, а затем вызывать соответствующий метод для вывода, когда это необходимо, экономя затраты на добавление полей и информации журнала:
if e := log.Debug(); e.Enabled() {
e.Str("foo", "bar").Msg("some debug message")
}
Первый запуск без параметров командной строки, по умолчаниюInfo
уровень,Debug
Лог не выводит:
$ go run main.go
{"level":"info","time":"2020-04-25T14:13:34+08:00","message":"This message appears when log level set to debug or info"}
плюс-debug
опции,Debug
а такжеInfo
Логи все выводят:
$ go run main.go -debug
{"level":"debug","time":"2020-04-25T14:18:19+08:00","message":"This message appears only when log level set to debug"}
{"level":"info","time":"2020-04-25T14:18:19+08:00","message":"This message appears when log level set to debug or info"}
{"level":"debug","foo":"bar","time":"2020-04-25T14:18:19+08:00","message":"some debug
message"}
Не выводить уровень и информацию
Иногда мы не хотим выводить уровни журнала (т.е.level
поле), вы можете использоватьlog.Log()
метод. Иногда у нас нет информации журнала для вывода, тогда мы передаем пустую строку вMsg()
метод:
func main() {
log.Log().
Str("foo", "bar").
Msg("")
}
бегать:
{"foo":"bar","time":"2020-04-25T14:19:48+08:00"}
СоздайтеLogger
Выше мы используем глобальныеLogger
, у этого способа есть очевидный недостаток: если где-то изменить настройки, это повлияет на глобальное логирование. Чтобы убрать этот эффект, нам нужно создать новыйLogger
:
func main() {
logger := zerolog.New(os.Stderr)
logger.Info().Str("foo", "bar").Msg("hello world")
}
перечислитьzerlog.New()
проходить вio.Writer
Так же, как автор журнала.
сынLogger
исходя из текущегоLogger
можно создать сабLogger
,сынLogger
может быть в родительскомLogger
Добавьте к нему несколько дополнительных полей. перечислитьlogger.With()
Создайте контекст, затем добавьте в него поля и, наконец, вызовитеLogger()
вернуть новыйLogger
:
func main() {
logger := zerolog.New(os.Stderr)
sublogger := logger.With().
Str("foo", "bar").
Logger()
sublogger.Info().Msg("hello world")
}
sublogger
будет дополнительно выводить"foo": "bar"
это поле.
настраивать
zerolog
Предусмотрены различные параметры для настройки поведения журнала ввода.
Украсьте вывод
zerolog
предоставилConsoleWriter
Выводит журналы с цветовой кодировкой для удобства чтения. перечислитьzerolog.Output()
включитьConsoleWriter
:
func main() {
logger := log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
logger.Info().Str("foo", "bar").Msg("hello world")
}
вывод:
Мы можем пойти дальшеConsoleWriter
Настройте, чтобы настроить уровень вывода, информацию, имя поля и формат значений поля:
func main() {
output := zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}
output.FormatLevel = func(i interface{}) string {
return strings.ToUpper(fmt.Sprintf("| %-6s|", i))
}
output.FormatMessage = func(i interface{}) string {
return fmt.Sprintf("***%s****", i)
}
output.FormatFieldName = func(i interface{}) string {
return fmt.Sprintf("%s:", i)
}
output.FormatFieldValue = func(i interface{}) string {
return strings.ToUpper(fmt.Sprintf("%s", i))
}
logger := log.Output(output).With().Timestamp().Logger()
logger.Info().Str("foo", "bar").Msg("hello world")
}
По сути, это установка хуков на уровни, информацию, имена полей и значения полей, и однократное преобразование их через функцию хука перед выводом:
ConsoleWriter
Производительность не идеальна, рекомендуется использовать только в среде разработки!
Установить автоматически добавляемые имена полей
Имя поля уровня по умолчанию в выходном журнале:level
, информация по умолчаниюmessage
, время по умолчанию равноtime
. в состоянии пройтиzerolog
серединаLevelFieldName/MessageFieldName/TimestampFieldName
устанавливать:
func main() {
zerolog.TimestampFieldName = "t"
zerolog.LevelFieldName = "l"
zerolog.MessageFieldName = "m"
logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
logger.Info().Msg("hello world")
}
вывод:
{"l":"info","t":"2020-04-25T14:53:08+08:00","m":"hello world"}
Обратите внимание, что этот параметр является глобальным! ! !
выходное имя файла и номер строки
Иногда нам нужно вывести имя файла и номер строки, чтобы мы могли быстро найти место кода и легко найти проблему. Это можно сделать, создав подLogger
принестиCaller()
Варианты завершены:
func main() {
logger := zerolog.New(os.Stderr).With().Caller().Logger()
logger.Info().Msg("hello world")
}
вывод:
{"level":"info","caller":"d:/code/golang/src/github.com/darjun/go-daily-lib/zerolog/setting/file-line/main.go:11","message":"hello world"}
выборка журнала
Иногда слишком много журналов мешают нам устранять неполадки.zerolog
Он поддерживает функцию выборки журнала, которая может быть выведена после каждого количества журналов, а остальные журналы отброшены:
func main() {
sampled := log.Sample(&zerolog.BasicSampler{N: 10})
for i := 0; i < 20; i++ {
sampled.Info().Msg("will be logged every 10 message")
}
}
В результате всего два вывода:
{"level":"info","time":"2020-04-25T15:01:02+08:00","message":"will be logged every 10 message"}
{"level":"info","time":"2020-04-25T15:01:02+08:00","message":"will be logged every 10 message"}
Есть более продвинутые настройки:
func main() {
sampled := log.Sample(&zerolog.LevelSampler{
DebugSampler: &zerolog.BurstSampler{
Burst: 5,
Period: time.Second,
NextSampler: &zerolog.BasicSampler{N: 100},
},
})
sampled.Debug().Msg("hello world")
}
Вышеприведенный код только образцыDebug
Log, в течение 1 с выводится максимум 5 журналов, а когда выводится более 5 журналов, один журнал выводится каждые 100 журналов.
крюк
zerolog
Поддержка хуков, мы можем добавить несколько дополнительных полей или сделать другие операции для разных уровней журнала:
type AddFieldHook struct {
}
func (AddFieldHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
if level == zerolog.DebugLevel {
e.Str("name", "dj")
}
}
func main() {
hooked := log.Hook(AddFieldHook{})
hooked.Debug().Msg("")
}
еслиDebug
уровень, дополнительный выход"name":"dj"
Поле:
{"level":"debug","time":"2020-04-25T15:09:04+08:00","name":"dj"}
представление
Что касается производительности, на GitHub есть подробный тест производительности сlogrus/zap
Сравнение других библиотек журналов. Если вам интересно, вы можете посетить:GitHub.com/life/zero log#….zerolog
коэффициент производительностиzap
Даже лучше!
Суммировать
Именно потому, что многие люди не удовлетворены существующим положением вещей, был достигнут технологический прогресс и красочный мир с открытым исходным кодом!
Если вы найдете забавную и простую в использовании языковую библиотеку Go, добро пожаловать, чтобы отправить вопрос на Go Daily Library GitHub😄
Ссылаться на
- нулевой журнал GitHub:github.com/rs/zerolog
- Перейти на ежедневный репозиторий GitHub:GitHub.com/Darenjun/go-of…
я
мой блог:darjun.github.io
Добро пожаловать, чтобы обратить внимание на мою общедоступную учетную запись WeChat [GoUpUp], учитесь вместе и добивайтесь прогресса вместе ~