Zerolog ежедневной библиотеки Go

Go

Введение

Существует множество библиотек ведения журналов для каждого языка программирования, потому что ведение журналов является обязательным в каждом проекте. Ранее мы представили стандартную библиотеку ведения журналов.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😄

Ссылаться на

  1. нулевой журнал GitHub:github.com/rs/zerolog
  2. Перейти на ежедневный репозиторий GitHub:GitHub.com/Darenjun/go-of…

я

мой блог:darjun.github.io

Добро пожаловать, чтобы обратить внимание на мою общедоступную учетную запись WeChat [GoUpUp], учитесь вместе и добивайтесь прогресса вместе ~