J'utilise logrus dans une application Go. Je pense que cette question est également applicable à tout autre logiciel de journalisation (qui ne propose pas de configuration basée sur un fichier externe).
logrus fournit des fonctions permettant de configurer diverses configurations, par exemple: SetOutput, SetLevel etc.
Comme toute autre application dont j'ai besoin pour me connecter à partir de plusieurs fichiers/packages source, il semble que vous deviez configurer ces options dans chaque fichier avec logrus.
Est-il possible de configurer ces options une fois quelque part dans un endroit central pour les partager dans toute l'application? Ainsi, si je dois modifier le niveau de journalisation, je peux le faire à un endroit et s’applique à tous les composants de l’application.
Vous n'avez pas besoin de définir ces options dans chaque fichier avec Logrus.
Vous pouvez importer Logrus en tant que log
:
import log "github.com/Sirupsen/logrus"
Ensuite, les fonctions telles que log.SetOutput()
ne sont que des fonctions. Elles modifient le journal global et s’appliquent à tout fichier contenant cette importation.
Vous pouvez créer une variable globale log
de package:
var log = logrus.New()
Ensuite, les fonctions telles que log.SetOutput()
sont des méthodes et modifient votre paquet global. C'est un peu gênant pour OMI si vous avez plusieurs packages dans votre programme, car chacun d'entre eux possède un enregistreur différent avec des paramètres différents (mais c'est peut-être bon pour certains cas d'utilisation). Je n’apprécie pas non plus cette approche car elle confond goimports
(qui voudra insérer log
dans votre liste d’importations).
Ou vous pouvez créer votre propre wrapper (c'est ce que je fais). J'ai mon propre paquet log
avec son propre logger
var:
var logger = logrus.New()
Ensuite, je crée des fonctions de haut niveau pour envelopper Logrus:
func Info(args ...interface{}) {
logger.Info(args...)
}
func Debug(args ...interface{}) {
logger.Debug(args...)
}
C'est un peu fastidieux, mais cela me permet d'ajouter des fonctions spécifiques à mon programme:
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))
}
Je peux donc faire des choses comme:
log.WithConn(c).Info("Connected")
(Je prévois à l'avenir d'encapsuler logrus.Entry
dans mon propre type afin de mieux les chaîner; pour l'instant, je ne peux pas appeler log.WithConn(c).WithRequest(r).Error(...)
car je ne peux pas ajouter WithRequest()
à logrus.Entry
.)
C’est la solution à laquelle j’ai abouti pour mon application et qui permet d’ajouter des champs au contexte de journalisation. Cela a un faible impact sur les performances en raison de la copie des champs de base de contexte.
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")
}