web-dev-qa-db-ja.com

Golang Logrus-集中構成を行う方法?

Goアプリでlogrusを使用しています。この質問は、他のロギングパッケージ(外部ファイルベースの構成を提供しないもの)にも適用できると思います。

logrusは、さまざまな構成をセットアップする機能を提供します。 SetOutput、SetLevelなど.

複数のソースファイル/パッケージからログを記録する必要がある他のアプリケーションと同様に、logrusを使用して各ファイルでこれらのオプションを設定する必要があるようです。

アプリケーション全体で共有するために、これらのオプションを中央のどこかに一度設定する方法はありますか?ロギングレベルを変更する必要がある場合は、1か所で行うことができ、アプリのすべてのコンポーネントに適用されます。

21
Dipen Bhikadya

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_。)

22
Rob Napier

これは、ロギングコンテキストへのフィールドの追加を可能にする私のアプリケーションのために到達したソリューションです。コンテキストベースのフィールドをコピーするため、パフォーマンスへの影響はわずかです。

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")
}
1
hurdlea