web-dev-qa-db-ja.com

log.Loggerを無効にする方法

logパッケージを利用する高度にインストゥルメントされたコードがあります。ロギングをオフにするときが来ました。標準のロガーをオフにする方法を判断できません。

私は何かを見逃しましたか?ログ呼び出しを行う前にフラグを確認する必要がありますか、それとも本番環境でコメントアウトする必要がありますか?

39
Matt Joiner

ログを完全に無効にするには、実際にはlog.SetFlags(0)を呼び出す方が適切ですジョリル 出力を何もしないio.Writerに設定します(つまり、log.SetOutput(ioutil.Discard)

しかし、この後でも、操作は約 500-600 ns/op でアイドル状態になります1

これは、カスタムLogger実装を使用して、すべての関数を何もしないように実装することで 100 ns/opまで)短縮できます-- (ここ (bervityの場合のみPrintlnをオーバーライドします)。

これらすべての代わりに、レベル付きのカスタムログフレームワークを使用し、完全にオフに設定することもできます。

ただし、ロギングによく使用されるライブラリの1つ( logrus )には パフォーマンスへの影響 があります---同じことが benchmarks にもあります関係なくK + ns/opで実行します。

偏った意見:ベンチマークから、ライブラリ go-logging は、Logger-1に設定すると、カスタムLevel実装と同等に機能します。バックエンドとフォーマット

(ベンチマークソースが見つかります ここ

ベンチマークの出力は次のとおりです。

testing: warning: no tests to run
PASS
BenchmarkGoLogging-4                                             1000000          2068 ns/op
BenchmarkGoLoggingNullBackend-4                                  5000000           308 ns/op
BenchmarkGoLoggingNullBackendWithFancyFormatter-4                3000000           435 ns/op
BenchmarkGoLoggingOffLevel-4                                    20000000           109 ns/op
BenchmarkGoLoggingNullBackendAndOffLevel-4                      20000000           108 ns/op
BenchmarkGoLoggingNullBackendWithFancyFormatterAndOffLevel-4    20000000           109 ns/op
BenchmarkLog15-4                                                  200000          7359 ns/op
BenchmarkLog15WithDiscardHandler-4                               2000000           922 ns/op
BenchmarkLog15WithDiscardHandlerAndOffLevel-4                    2000000           926 ns/op
BenchmarkLog15WithNopLogger-4                                   20000000           108 ns/op
BenchmarkLog15WithNopLoggerDiscardHandlerA-4                    20000000           112 ns/op
BenchmarkLog15WithNopLoggerAndDiscardHandlerAndOffLevel-4       20000000           112 ns/op
BenchmarkLog-4                                                   1000000          1217 ns/op
BenchmarkLogIoDiscardWriter-4                                    2000000           724 ns/op
BenchmarkLogIoDiscardWriterWithoutFlags-4                        3000000           543 ns/op
BenchmarkLogCustomNullWriter-4                                   2000000           731 ns/op
BenchmarkLogCustomNullWriterWithoutFlags-4                       3000000           549 ns/op
BenchmarkNopLogger-4                                            20000000           113 ns/op
BenchmarkNopLoggerWithoutFlags-4                                20000000           112 ns/op
BenchmarkLogrus-4                                                 300000          3832 ns/op
BenchmarkLogrusWithDiscardWriter-4                                500000          3032 ns/op
BenchmarkLogrusWithNullFormatter-4                                500000          3814 ns/op
BenchmarkLogrusWithPanicLevel-4                                   500000          3872 ns/op
BenchmarkLogrusWithDiscardWriterAndPanicLevel-4                   500000          3085 ns/op
BenchmarkLogrusWithDiscardWriterAndNullFormatterAndPanicLevel-4   500000          3064 ns/op
ok      log-benchmarks  51.378s
go test -bench .  62.17s user 3.90s system 126% cpu 52.065 total

#1:[〜#〜] ymmv [〜#〜]、i7-4500U CPU @ 1.80GHzでテスト

30
Avinash R

Io/ioutilパッケージに存在する場合、一般的なio.Writerに独自のタイプを作成する理由はありません。

import (
    "log"
    "io/ioutil"
)

func init() {
    log.SetOutput(ioutil.Discard)
}
110
Jeff Wendling
type NullWriter int
func (NullWriter) Write([]byte) (int, error) { return 0, nil }

// ...

log.SetOutput(new(NullWriter))
5
Mostafa

このアプローチでは、実行時にロギングをオンまたはオフにできます。

type LogWriter struct{
    enabled bool
}

func (l *LogWriter) Enable() {
    l.enabled = true
}

func (l *LogWriter) Disable() {
    l.enabled = false
}

func (l *LogWriter) Write([]byte) (int, error) {
    if l.enabled {
        //...
    }
    return 0, nil
}

そして、このアプローチはランタイム全体のロギングを有効または無効にします。

type LogWriter struct{}

func (l *LogWriter) Write([]byte) (int, error) {
    if some.Constant {
        //...
    }
    return 0, nil
}

どこ some.Constantは、コンパイル前に設定する定数("production"バイナリを生成する)、またはコマンドラインフラグ(myprogram --enable-logging=true

どちらのアプローチでも、現在のコードをほとんどそのままにしておくことができます。

3
thwd

SetOutput()はグローバルロガーに対してのみ定義されているため、カスタムライターは他のロガーにとっても便利です。簡単な記述方法は次のとおりです。

type LogWriter struct{ io.Writer }
func (w *LogWriter) Enable()  { w.Writer = os.Stdout }
func (w *LogWriter) Disable() { w.Writer = ioutil.Discard }
2
TJM

この機能や他のログ機能を探すためにここに来る他の人への注意:ログの無効化、ログレベルの設定、ログのローテーション、ファイルへのリダイレクトなど、役立つと思われるlog4goパッケージをご覧ください。

http://godoc.org/code.google.com/p/log4go にあるドキュメントを参照してください

1
Kenny Grant