Goアプリでlogrusを使用しています。この質問は、他のロギングパッケージ(外部ファイルベースの構成を提供しないもの)にも適用できると思います。
logrusは、さまざまな構成をセットアップする機能を提供します。 SetOutput、SetLevelなど.
複数のソースファイル/パッケージからログを記録する必要がある他のアプリケーションと同様に、logrusを使用して各ファイルでこれらのオプションを設定する必要があるようです。
アプリケーション全体で共有するために、これらのオプションを中央のどこかに一度設定する方法はありますか?ロギングレベルを変更する必要がある場合は、1か所で行うことができ、アプリのすべてのコンポーネントに適用されます。
Logrusで各ファイルにこれらのオプションを設定する必要はありません。
Logrusはlog
としてインポートできます。
_import log "github.com/Sirupsen/logrus"
_
次に、log.SetOutput()
のような関数は単なる関数であり、グローバルロガーを変更し、このインポートを含むすべてのファイルに適用されます。
パッケージのグローバルlog
変数を作成できます。
_var log = logrus.New()
_
次に、log.SetOutput()
のような関数はメソッドであり、パッケージをグローバルに変更します。プログラムに複数のパッケージがある場合、これは厄介なIMOです。これは、パッケージごとに異なる設定の異なるロガーがあるためです(ただし、いくつかのユースケースではそれが良いかもしれません)。 goimports
を混乱させるため、この方法も好きではありません(インポートリストにlog
を挿入する必要があります)。
または、独自のラッパーを作成することもできます(これは私が行うことです)。独自のlog
varを含む独自の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")
}