2012-05-13 19 views
24

私は、logパッケージを使用するコードを多用しています。今、ロギングをオフにするときが来たので、標準ロガーをオフにする方法を決定することはできません。Go:log.Loggerを無効にしますか?

私は何かを見逃しましたか?ログコールを行う前にフラグをチェックするのか、プロダクションでコメントするべきなのでしょうか?

答えて

10

、それはlog.SetFlags(0)Jorilを呼び出し、ノーオペレーションio.Writer(すなわち、log.SetOutput(ioutil.Discard)

への出力を設定するために、実際に良いでしょうしかし、たとえこの後、操作はこれはまだ笙をカットすることができます周り500-600 ns/op

アイドルます(bervityの場合にのみPrintlnを上書きする)のように、すべての機能をノーオペレーションにすることによって、rt(約100ns/opまで)

これらのすべての代替手段は、レベルを持つカスタムログフレームワークを使用してオフに設定することです。

注ログインするための一般的に使用されるライブラリのかかわらず、一方(logrus)はperformance implicationsを有する - と同じに関係なく、それは/ OP3K + NSで実行benchmarksに見出すことができます。

偏った意見:ベンチマークから、カスタムLogger実装と同等でライブラリgo-logging行いかかわらず、バックエンドの、-1Levelを設定し、

をフォーマット(ベンチマークソースはhereを見つけることができます)

次のようにベンチマークの出力は、次のとおり

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:i7-4500U CPUの@の1.80GHzでテストメーリングリストへ

5
type NullWriter int 
func (NullWriter) Write([]byte) (int, error) { return 0, nil } 

// ... 

log.SetOutput(new(NullWriter)) 
+1

は、それはおそらく 'int'戻り値が'であればライターの一部のユーザーが書き込みを続行しようとした場合のだろう0? (つまり、引数が 'b [] byte'のとき' len(b) 'を返すべきでしょうか) – Ashe

+2

一般的にあなたは正しいですが、' log'パッケージは[無視します](http://code.google.com /p/go/source/browse/src/pkg/log/log.go#153) 'int'を返す値なので、プロダクションコードのような頻繁な関数で時間を無駄にしない方が良いでしょう。 – Mostafa

+2

Goに 'log'を使用する際のベストプラクティスはありますか?ほとんどのロギングコールは、トレース目的であれば、最終的に削除(またはコメントアウト)されますか? –

3

このアプローチは、あなたが実行時にログオンしてオフにすることができます:

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だろうコンパイルする前に設定した定数("生産"バイナリ)または変数コマンドラインフラグ(myprogram --enable-logging=trueのようなもの)を介してプログラムを実行するときに1回だけ設定できる。

両方の方法で、現在のコードをほとんど変更しないでおくことができます。

84

io/ioutilパッケージに共通のio.Writerが存在する場合、独自のタイプを作成する理由はありません。他の人はこれと他のロギング機能を探してここに来るため

import (
    "log" 
    "io/ioutil" 
) 

func init() { 
    log.SetOutput(ioutil.Discard) 
} 
+0

素晴らしい発見!私は標準ライブラリでそのようなものを探しましたが、 'io/ioutil'はチェックしませんでした。 – Mostafa

+0

これは、パッケージまたはアプリケーション全体のロガーのみを無効にしますか? – Kiril

+1

これはディスクへの書き込みをスキップしますが、まだすべての書式設定を行いますので、 'log.SetFlags(0)'を呼び出すと少し楽になります。 – Joril

1

注:それは、ログレベルを設定し、ロギングをオフにするカバーとしてlog4goパッケージを見て、ログローテーション、あるかもしれないファイルなどへのリダイレクト有用。

は唯一のグローバルロガーのために定義されて SetOutput()以来 http://godoc.org/code.google.com/p/log4go

2

のドキュメントを参照してください、カスタムライターは、まだ他のロガーに便利です。 1を書くの短い方法は、このようなものです:完全にログを無効にするために

type LogWriter struct{ io.Writer } 
func (w *LogWriter) Enable() { w.Writer = os.Stdout } 
func (w *LogWriter) Disable() { w.Writer = ioutil.Discard } 
関連する問題