1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-logrus

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Logrus — это структурированный логгер для Go (golang), полностью совместимый с API стандартного логгера библиотеки.

Logrus находится в режиме обслуживания. Мы не будем вводить новые функции. Слишком сложно сделать это так, чтобы не нарушить работу многих проектов, а это последнее, что вы хотите от своей библиотеки логирования (опять же...).

Это не значит, что Logrus мёртв. Logrus будет продолжать поддерживаться в плане безопасности, (обратной совместимости) исправлений ошибок и производительности (где мы ограничены интерфейсом).

Я считаю, что самый большой вклад Logrus заключается в том, что он сыграл свою роль в сегодняшнем широком использовании структурированного логирования в Golang. Кажется, нет причин делать серьёзную, ломающую итерацию в Logrus V2, поскольку фантастическое сообщество Go создало их самостоятельно. Появилось много фантастических альтернатив. Logrus выглядел бы как они, если бы был перепроектирован с учётом того, что мы знаем о структурированном логировании в Go сегодня. Посмотрите, например, Zerolog, Zap и Apex.

Видите странные проблемы с чувствительностью к регистру? Раньше можно было импортировать Logrus как в верхнем, так и в нижнем регистре. Из-за среды пакета Go это вызывало проблемы в сообществе, и нам нужен был стандарт. В некоторых средах возникали проблемы с вариантом в верхнем регистре, поэтому был выбран нижний регистр. Всё, что использует logrus, должно использовать нижний регистр: github.com/sirupsen/logrus. Любой пакет, который этого не делает, должен быть изменён.

Чтобы исправить Glide, см. эти комментарии. Для подробного объяснения проблемы с регистром см. этот комментарий.

Красиво раскрашен при разработке (когда подключён TTY, в противном случае просто текст):

С log.SetFormatter(&log.JSONFormatter{}), для лёгкого разбора logstash или Splunk:

{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}

{"level":"warning","msg":"The group's number increased tremendously!", "number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}

{"animal":"walrus","level":"info","msg":"A giant walrus appears!", "size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}

{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", "size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}

{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, "time":"2014-03-10 19:57:38.562543128 -0400 EDT"}

Со стандартным log.SetFormatter(&log.TextFormatter{}), когда TTY не подключён, вывод совместим с форматом logfmt:

time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} Мы обнаружили, что этот API заставляет вас думать о логировании таким образом, который создаёт гораздо более полезные сообщения. Мы были в бесчисленных ситуациях, когда всего лишь одно добавленное поле к уже существующему сообщению журнала сэкономило бы нам часы. Вызов WithFields является необязательным.

В общем, при использовании Logrus использование любых функций семейства printf следует рассматривать как подсказку о том, что вы должны добавить поле, однако вы всё равно можете использовать функции семейства printf с Logrus.

#### Стандартные поля

Часто бывает полезно всегда иметь поля, прикреплённые к сообщениям журнала в приложении или его частях. Например, вы можете захотеть всегда регистрировать request_id и user_ip в контексте запроса. Вместо того чтобы писать log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip}) на каждой строке, вы можете создать logrus.Entry для передачи:

```go
requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
requestLogger.Info("something happened on that request") # will log request_id and user_ip
requestLogger.Warn("something not great happened")

Перехватчики

Вы можете добавлять перехватчики для уровней логирования. Например, чтобы отправлять ошибки в службу отслеживания исключений на Error, Fatal и Panic, информацию в StatsD или регистрировать в нескольких местах одновременно, например, в syslog.

Logrus поставляется со встроенными перехватчиками (hooks/). Добавьте их или свой собственный перехватчик в init:

import (
  log "github.com/sirupsen/logrus"
  "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
  logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
  "log/syslog"
)

func init() {

  // Используйте перехватчик Airbrake, чтобы сообщать об ошибках, которые имеют уровень серьёзности Error или выше, службе отслеживания исключений. Вы можете создавать собственные перехватчики, см. раздел «Перехватчики».
  log.AddHook(airbrake.NewHook(123, "xyz", "production"))

  hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
  if err != nil {
    log.Error("Unable to connect to local syslog daemon")
  } else {
    log.AddHook(hook)
  }
}

Примечание: Syslog hook также поддерживает подключение к локальному syslog (например, "/dev/log" или "/var/run/syslog" или "/var/run/log"). Для получения подробной информации ознакомьтесь с README syslog hook (hooks/syslog/README.md).

Список известных служб перехватчиков можно найти на этой вики-странице (https://github.com/sirupsen/logrus/wiki/Hooks).

Уровни логирования

У Logrus есть семь уровней логирования: Trace, Debug, Info, Warning, Error, Fatal и Panic.

log.Trace("Something very low level.")
log.Debug("Useful debugging information.")
log.Info("Something noteworthy happened!")
log.Warn("You should probably take a look at this.")
log.Error("Something failed but I'm not quitting.")
// Calls os.Exit(1) after logging
log.Fatal("Bye.")
// Calls panic() after logging
log.Panic("I'm bailing.")

Вы можете установить уровень логирования для Logger, после чего он будет регистрировать только записи с этим уровнем серьёзности или любым выше него:

// Будет регистрировать всё, что является информацией или выше (предупреждение, ошибка, фатальная ошибка, паника). По умолчанию.
log.SetLevel(log.InfoLevel)

Может быть полезно установить log.Level = logrus.DebugLevel в среде отладки или подробного описания, если ваше приложение имеет такую возможность.

Примечание: Если вы хотите разные уровни логирования для глобального (log.SetLevel(...)) и системного логирования, пожалуйста, ознакомьтесь с README системного перехватчика (hooks/syslog/README.md#different-log-levels-for-local-and-remote-logging).

Записи

Помимо полей, добавленных с помощью WithField или WithFields, некоторые поля автоматически добавляются ко всем событиям логирования:

  1. time. Метка времени, когда была создана запись.
  2. msg. Сообщение логирования, переданное в {Info,Warn,Error,Fatal,Panic} после вызова AddFields. Например, Failed to send event.
  3. level. Уровень логирования. Например, info.

Среды

У Logrus нет понятия среды.

Если вы хотите, чтобы перехватчики и форматировщики использовались только в определённых средах, вам следует справиться с этим самостоятельно. Например, если у вашего приложения есть глобальная переменная Environment, которая представляет собой строковое представление среды, вы могли бы сделать следующее: ``` лог "github.com/sirupsen/logrus" )

func init() { // делаем что-то здесь, чтобы установить окружение в зависимости от переменной окружения // или флага командной строки if Environment == "production" { лог.SetFormatter(&лог.JSONFormatter{}) } else { // TextFormatter используется по умолчанию, на самом деле вам не нужно этого делать. лог.SetFormatter(&лог.TextFormatter{})


Эта конфигурация предназначена для использования `logrus`, но JSON в
производстве в основном полезен только если вы выполняете агрегацию журналов с помощью таких инструментов, как
Splunk или Logstash.

#### Форматировщики

Встроенные форматировщики журналов:

* `logrus.TextFormatter`. Регистрирует событие в цвете, если stdout является tty, в противном случае
без цвета.
* *Примечание:* чтобы принудительно выводить цветной вывод, когда нет TTY, установите поле `ForceColors`
в `true`. Чтобы принудительно отключить цветной вывод, даже если есть TTY, установите поле `DisableColors` в `true`. Для Windows см.
[github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
* По умолчанию уровни усекаются до 4 символов. Чтобы отключить
усечение, установите для поля `DisableLevelTruncation` значение `true`.
* При выводе на TTY часто бывает полезно визуально сканировать вниз по столбцу, где все уровни имеют одинаковую ширину. Установка поля `PadLevelText` в `true` включает это поведение, добавляя отступ к тексту уровня.
* Все параметры перечислены в [сгенерированных документах](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
* `logrus.JSONFormatter`. Записывает поля в формате JSON.
* Все опции перечислены в [сгенерированных документах](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).

Сторонние форматировщики журналов:

* [`FluentdFormatter`](https://github.com/joonix/log). Форматирует записи, которые могут быть проанализированы Kubernetes и Google Container Engine.
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Форматирует записи в соответствии со спецификацией Graylog's [GELF 1.1](http://docs.graylog.org/en/2.4/pages/gelf.html).
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Записывает поля как события [Logstash](http://logstash.net).
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Отображает источник записи вместе с альтернативным макетом.
* [`zalgo`](https://github.com/aybabtme/logzalgo). Вызов силы Зальго.
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Преобразует поля logrus в вложенную структуру.
* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). Получает имя файла, номер строки журнала и имя последней функции при печати журнала; сохраняет журнал в файлы.
* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). Форматер сообщений logrus с добавлением удобочитаемой подписи.

Вы можете определить свой собственный форматировщик, реализовав интерфейс `Formatter`, требующий метода `Format`. `Формат` принимает `*Entry`. `entry.Data` — это тип `Fields` (`map[string]interface{}`) со всеми вашими полями, а также с полями по умолчанию (см. раздел «Записи» выше):

```go
type MyJSONFormatter struct {
}

лог.SetFormatter(new(MyJSONFormatter))

func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
// Обратите внимание, что это не включает Time, Level и Message, которые доступны в
// Entry. Обратитесь к `godoc` за информацией об этих полях или прочитайте исходный код официальных регистраторов.
serialized, err := json.Marshal(entry.Data)
  if err != nil {
    return nil, fmt.Errorf("Не удалось маршалировать поля в JSON, %w", err)
  }
return append(serialized, '\n'), nil
}

Регистратор как io.Writer

Logrus можно преобразовать в io.Writer. Этот писатель является концом io.Pipe, и вы должны закрыть его.

w := logger.Writer()
defer w.Close()

srv := http.Server{
    // создать стандартный регистратор log.Logger, который записывает в
    // logrus.Logger.
    ErrorLog: log.New(w, "", 0),
}

Каждая строка, записанная в этот писатель, будет напечатана обычным способом с использованием форматировщиков и хуков. Уровень для этих записей — info.

Это означает, что мы можем легко переопределить стандартный библиотечный регистратор: logger := logrus.New()

logger.Formatter = &logrus.JSONFormatter{}

// Используем logrus для стандартного вывода логов // Обратите внимание, что здесь log ссылается на стандартный библиотечный log, а не на logrus, импортированный под именем log. log.SetOutput(logger.Writer())

Ротация логов

Logrus не предоставляет ротацию логов. Ротацию логов должна выполнять внешняя программа (например, logrotate(8)), которая может сжимать и удалять старые записи логов. Это не должно быть функцией регистратора уровня приложения.

Инструменты

Инструмент Описание
Logrus Mate Logrus mate — это инструмент для Logrus, который позволяет управлять регистраторами. Вы можете настроить уровень, хук и форматировщик регистратора через конфигурационный файл. Регистратор будет создан с различными конфигурациями в разных средах.
Logrus Viper Helper Помощник для Logrus, чтобы работать с spf13/Viper для загрузки конфигурации с fangs! И упростить конфигурацию Logrus, используя некоторые функции Logrus Mate. Пример

Тестирование

В Logrus есть встроенная функция для проверки наличия сообщений логов, реализованная через хук test и предоставляющая:

  • декораторы для существующего регистратора (test.NewLocal и test.NewGlobal), которые просто добавляют хук test;
  • тестовый регистратор (test.NewNullLogger), который просто записывает сообщения логов (и не выводит их):
import(
  "github.com/sirupsen/logrus"
  "github.com/sirupsen/logrus/hooks/test"
  "github.com/stretchr/testify/assert"
  "testing"
)

func TestSomething(t*testing.T){
  logger, hook := test.NewNullLogger()
  logger.Error("Helloerror")

  assert.Equal(t, 1, len(hook.Entries))
  assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
  assert.Equal(t, "Helloerror", hook.LastEntry().Message)

  hook.Reset()
  assert.Nil(t, hook.LastEntry())
}

Обработчики фатальных ошибок

Logrus может регистрировать одну или несколько функций, которые будут вызываться при регистрации любого сообщения уровня fatal. Зарегистрированные обработчики будут выполняться перед тем, как logrus выполнит os.Exit(1). Такое поведение может быть полезно, если вызывающим объектам необходимо корректно завершить работу. В отличие от вызова panic("Something went wrong..."), который можно перехватить с помощью отложенного recover, вызов os.Exit(1) не может быть перехвачен.

...
handler := func() {
  // корректно завершаем работу...
}
logrus.RegisterExitHandler(handler)
...

Безопасность потоков

По умолчанию Logger защищён мьютексом для одновременной записи. Мьютекс удерживается при вызове хуков и записи логов. Если вы уверены, что такая блокировка не требуется, вы можете вызвать logger.SetNoLock(), чтобы отключить блокировку.

Ситуация, когда блокировка не нужна, включает:

  • у вас нет зарегистрированных хуков, или вызов хуков уже является потокобезопасным;
  • запись в logger.Out уже является потокобезопасной, например:
    1. logger.Out защищён замками.
    2. logger.Out — это обработчик os.File, открытый с флагом O_APPEND, и каждая запись меньше 4k. (Это позволяет многопоточную/многопроцессную запись) (См. http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Logrus — это структурированный, подключаемый фреймворк для логирования на Go, который полностью совместим с интерфейсом официальной библиотеки log. Развернуть Свернуть
MIT
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/mirrors-logrus.git
git@api.gitlife.ru:oschina-mirror/mirrors-logrus.git
oschina-mirror
mirrors-logrus
mirrors-logrus
master