ozzo-log это Go-пакет предоставляющий расширенную поддержку логирования для Go программ. Он имеет следующие свойства:
- Высокую производительность за счет применения асинхронного логирования;
- Логирование сообщений с различными уровнями важности;
- Логирование сообщений по категориям;
- Логирование стека вызовов (call stacks);
- Фильтрацию по уровням важности и категориям;
- Настраиваемый формат сообщений;
- Поддерживает различные поставщики вывода и сохраниения через настраиваемые и подключаемые обработчики сообщений;
- Обработчики для консоли, файла, сети и электронной почты уже имеются по умолчанию.
Go 1.2 или выше.
Выполните данные команды для установки:
go get github.com/go-ozzo/ozzo-log
Представленный ниже код показывает как вы можете использовать пакет.
package main
import (
"github.com/go-ozzo/ozzo-log"
)
func main() {
// создаем логгер
logger := log.NewLogger()
// добавляем вывод в консоль и файл
t1 := log.NewConsoleTarget()
t2 := log.NewFileTarget()
t2.FileName = "app.log"
t2.MaxLevel = log.LevelError
logger.Targets = append(logger.Targets, t1, t2)
// открываем логгер
logger.Open()
// вызываем методы для вывода в лог различных сообщений
logger.Error("plain text error")
logger.Error("error with format: %v", true)
logger.Debug("some debug info")
// настраиваем категории логирования
l := logger.GetLogger("app.services")
l.Info("some info")
l.Warning("some warning")
...
logger.Close()
}
Логгер предоставляет различные методы жарналирования, которые могут быть вызваны кодом приложения, для записи сообщений различной степени важности.
Фильтры сообщений по важности и по категориям сообщений позволяют обрабатывать сообщения различными способами, например одни сохраняя в файл, а другие посылая по электронной почте и т.д.
Логгер может иметь несколько способов обработки сообщений с различными условиями фильтрации.
В пакет ozzo-log уже включены основные цели.
ConsoleTarget
: отображает отфильтрованные сообщения в консолиFileTarget
: сохраняет отфильтрованные сообщения в файл (поддерживается ротация файлов)NetworkTarget
: отсылает сообщения по какому либо адресу в сетиMailTarget
: посылает необходимые сообщения на электронную почту
Вы можете создать логгер, настроить вывод, и запустить логирование при помощи данного кода:
// содаем главный логгер
logger := log.NewLogger()
logger.Targets = append(logger.Targets, target1, target2, ...)
logger.Open()
...здесь вызываем различные методы логирования...
logger.Close()
Вы можете сохранять сообщения определенного уровня важности (в соответствии со стандартом RFC5424)
посредством вывода предопределенных методов в структуре Logger
:
Emergency()
: система непригодна для использования.Alert()
: действия должны быть предприняты немедленно.Critical()
: критические условия.Error()
: состояния ошибки.Warning()
: различные предупреждения.Notice()
: нормальные, но существенные условия.Info()
: информационные цели.Debug()
: цели отладки.
Каждое сообщение в журнале связано с некой категорией, которая используется для группировки записей. Например, вы можете использовать категорию для записи сообщений какого либо Go пакета. Это позволяет вам выборочно отправлять ваши сообщения на нужные приемники, например в определенный файл или на определенную почту.
Если вы вызываете log.NewLogger()
, то вы получаете главный логгер с категорией app
для регистрации сообщений. Для сбора сообщений
с отличной категорией, вызовете метод GetLogger()
главного или родительского логгера для получения логгера потомка
и затем уже вызовете его метод для логирования сообщения:
logger := log.NewLogger()
// записывает сообщения с категорией "app"
logger.Error("...")
l1 := logger.GetLogger("system")
// записывает сообщения с категорией "system"
l1.Error("...")
l2 := l1.GetLogger("app.models")
// записыват сообщения с категорией "app.models"
l2.Error("...")
По умолчанию каждое сообщение имет свой формат для отсылки на различные получатели:
2015-10-22T08:39:28-04:00 [Error][app.models] что-то не так
...стек вызова (если включено)...
Вы может настоить собственный формат сообщений при помощи вызова Logger.GetLogger()
. Например,
logger := log.NewLogger()
logger = logger.GetLogger("app", func (l *Logger, e *Entry) string {
return fmt.Sprintf("%v [%v][%v] %v%v", e.Time.Format(time.RFC822Z), e.Level, e.Category, e.Message, e.CallStack)
})
По умолчанию сообщения всех уровней важности будут записаны. Вы можете изменить Logger.MaxLevel
чтобы изменить это поведение. Например,
logger := log.NewLogger()
// сохранять сообщения только между уровнями Emergency и Warning
logger.MaxLevel = log.LevelWarning
Кроме фильтрации на уровне логгеров, более тонка фильтрация может быть настроена на уровне целей.
Для каждой цели вы можете определить его собственный MaxLevel
так же как и у логгера;
Вы также можете определить какие категории сообщений цель должна принимать. Например,
target := log.NewConsoleTarget()
// принимает сообщения между уровнями Emergency и Info
target.MaxLevel = log.LevelInfo
// обрабатывает сообщения начинающиеся с "system.db." или "app."
target.Categories = []string{"system.db.*", "app.*"}
Когда приложение развертывается на продакшене, то нужно дать возможность настраивать логирование без перекомпиляции приложения. ozzo-log разработан с учетом этого.
Например, вы можете использовать JSON файл, чтобы приложение знало как оно должно настроить свой журнал:
{
"Logger": {
"Targets": [
{
"type": "ConsoleTarget",
},
{
"type": "FileTarget",
"FileName": "app.log",
"MaxLevel": 4 // Предупреждения или ниже
}
]
}
}
Если предположить что имя JSON файла app.json
, код вашего приложения может использовать пакет ozzo-config
для загрузки этого
JSON файла и конфигурирования логгера в приложении:
package main
import (
"github.com/go-ozzo/ozzo-config"
"github.com/go-ozzo/ozzo-log"
)
func main() {
c := config.New()
c.Load("app.json")
// регистрация типов целей для настройки целей логгера Logger.Targets.
c.Register("ConsoleTarget", log.NewConsoleTarget)
c.Register("FileTarget", log.NewFileTarget)
logger := log.NewLogger()
if err := c.Configure(logger, "Logger"); err != nil {
panic(err)
}
}
чтобы изменить конфигурацию логгера просто измените конфигурационный JSON файл без прекомиляции исходных фалов на Go.