Введение
Существует множество библиотек ведения журналов для каждого языка программирования, потому что ведение журналов является обязательным в каждом проекте. Ранее мы представили стандартную библиотеку ведения журналов.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")
}
Вышеприведенный код только образцыDebugLog, в течение 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], учитесь вместе и добивайтесь прогресса вместе ~