log
パッケージを利用する高度にインストゥルメントされたコードがあります。ロギングをオフにするときが来ました。標準のロガーをオフにする方法を判断できません。
私は何かを見逃しましたか?ログ呼び出しを行う前にフラグを確認する必要がありますか、それとも本番環境でコメントアウトする必要がありますか?
ログを完全に無効にするには、実際には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でテスト
Io/ioutilパッケージに存在する場合、一般的なio.Writerに独自のタイプを作成する理由はありません。
import (
"log"
"io/ioutil"
)
func init() {
log.SetOutput(ioutil.Discard)
}
type NullWriter int
func (NullWriter) Write([]byte) (int, error) { return 0, nil }
// ...
log.SetOutput(new(NullWriter))
このアプローチでは、実行時にロギングをオンまたはオフにできます。
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
)
どちらのアプローチでも、現在のコードをほとんどそのままにしておくことができます。
SetOutput()
はグローバルロガーに対してのみ定義されているため、カスタムライターは他のロガーにとっても便利です。簡単な記述方法は次のとおりです。
type LogWriter struct{ io.Writer }
func (w *LogWriter) Enable() { w.Writer = os.Stdout }
func (w *LogWriter) Disable() { w.Writer = ioutil.Discard }
この機能や他のログ機能を探すためにここに来る他の人への注意:ログの無効化、ログレベルの設定、ログのローテーション、ファイルへのリダイレクトなど、役立つと思われるlog4goパッケージをご覧ください。
http://godoc.org/code.google.com/p/log4go にあるドキュメントを参照してください