Голанг логрус - как сделать централизованную настройку?
Я использую logrus в приложении Go. Я считаю, что этот вопрос применим и к любому другому пакету журналирования (который не предлагает конфигурацию на основе внешних файлов).
logrus предоставляет функции для настройки различных конфигураций, например, SetOutput, SetLevel и т. д.
Как и в любом другом приложении, которое мне нужно для ведения журнала из нескольких исходных файлов / пакетов, кажется, что вам нужно настроить эти параметры в каждом файле с помощью logrus.
Есть ли способ настроить эти параметры один раз где-нибудь в центральном месте, чтобы обмениваться ими по всему приложению. Таким образом, если мне нужно изменить уровень ведения журнала, я могу сделать это в одном месте и применить ко всем компонентам приложения.
2 ответа
Вам не нужно устанавливать эти параметры в каждом файле с помощью Logrus.
Вы можете импортировать Logrus как log
:
import log "github.com/Sirupsen/logrus"
Тогда функции как log.SetOutput()
это всего лишь функции и изменяют глобальный регистратор и применяются к любому файлу, который включает этот импорт.
Вы можете создать глобальный пакет log
переменная:
var log = logrus.New()
Тогда функции как log.SetOutput()
методы и изменить ваш пакет глобальным. Это неудобно для IMO, если в вашей программе несколько пакетов, потому что у каждого из них есть свой регистратор с разными настройками (но, возможно, это хорошо для некоторых случаев использования). Мне также не нравится этот подход, потому что он сбивает с толку goimports
(который захочет вставить log
в ваш список импорта).
Или вы можете создать свою собственную обертку (что я и делаю). У меня есть своя log
пакет со своим logger
вар:
var logger = logrus.New()
Затем я делаю функции верхнего уровня, чтобы обернуть Logrus:
func Info(args ...interface{}) {
logger.Info(args...)
}
func Debug(args ...interface{}) {
logger.Debug(args...)
}
Это немного утомительно, но позволяет мне добавлять функции, специфичные для моей программы:
func WithConn(conn net.Conn) *logrus.Entry {
var addr string = "unknown"
if conn != nil {
addr = conn.RemoteAddr().String()
}
return logger.WithField("addr", addr)
}
func WithRequest(req *http.Request) *logrus.Entry {
return logger.WithFields(RequestFields(req))
}
Так что я могу делать такие вещи, как:
log.WithConn(c).Info("Connected")
(Планирую в будущем завернуть logrus.Entry
в мой собственный тип, чтобы я мог связать их лучше; в настоящее время я не могу позвонить log.WithConn(c).WithRequest(r).Error(...)
потому что я не могу добавить WithRequest()
в logrus.Entry
.)
Это решение, к которому я пришел для своего приложения, позволяет добавлять поля в контекст ведения журнала. Это оказывает небольшое влияние на производительность из-за копирования контекстных базовых полей.
package logging
import (
log "github.com/Sirupsen/logrus"
)
func NewContextLogger(c log.Fields) func(f log.Fields) *log.Entry {
return func(f log.Fields) *log.Entry {
for k, v := range c {
f[k] = v
}
return log.WithFields(f)
}
}
package main
import (
"logging"
)
func main {
app.Logger = logging.NewContextLogger(log.Fields{
"module": "app",
"id": event.Id,
})
app.Logger(log.Fields{
"startTime": event.StartTime,
"endTime": event.EndTime,
"title": event.Name,
}).Info("Starting process")
}