log の Writer を Discard してみる
golang のログ難しい・・・
特定のログレベルが指定されたときだけログ出力を有効化できるようになっているといいんじゃないかと思った。 ほんとはもっと自由に設定できるようになって欲しいけど。
とりあえずの実装はこんな感じ。
環境変数 LOG_LEVEL
に debug
が指定されたら出力する、それ以外では出さない。
io.Writer
な変数( ioutil.Discard
から推論されてるはず) に *os.File
な os.Stdout
を代入できるのは (*File) Write
があるからだと思う。
プロジェクト固有の実装でこういうのがあったら辛いなぁ。
package main import ( "io/ioutil" "log" "os" ) var logger *log.Logger func init() { writer := ioutil.Discard if os.Getenv("LOG_LEVEL") == "debug" { writer = os.Stdout } logger = log.New(writer, "[main] ", log.LstdFlags) } func Log() { logger.Println("aaabbbccc") }
ログ出力が無効な状態で性能落ちてもいやなので、簡単にベンチマーク。
package main import ( "testing" ) func BenchmarkLog(b *testing.B) { for n := 0; n < b.N; n++ { Log() } }
これを環境変数指定して2回実行。
go test -bench=. > discard_bench.txt LOG_LEVEL=debug go test -bench=. > stdout_bench.txt
そうすると次のような感じになった。
ざっくり 14 倍のオーバーヘッド (5169/361 = 14.3
)。
プロジェクトの都合で使ってるロギングライブラリがあるときはダメだけど、そうでなければなんか利用できそう。
実行方法 | 繰り返し回数 | 呼び出しあたりの時間 |
---|---|---|
無効化 | 5,000,000 | 361 ns/op |
有効化 | 200,000 | 5169 ns/op |