Go言語のロガー実装の1つにhashicorp/logutilsというシンプルなライブラリがあります。Goの標準パッケージ log
を拡張するようなもので、覚えることも少ないですし、他のライブラリと組み合わせやすい点もメリットです。
利用例は次のようになります。
package main
import (
"log"
"os"
"github.com/hashicorp/logutils"
)
func main() {
filter := &logutils.LevelFilter{
Levels: []logutils.LogLevel{"DEBUG", "WARN", "ERROR"},
MinLevel: logutils.LogLevel("WARN"),
Writer: os.Stderr,
}
log.SetOutput(filter)
log.Print("[DEBUG] Debugging") // 表示されない
log.Print("[WARN] Warning") // 表示される
log.Print("[ERROR] Erring") // 表示される
log.Print("Message I haven't updated") // 表示される
}
このように、ログ文字列先頭の[WARN]
などでログレベルを指定する仕様です。ログレベルはMinLevel
で指定して、指定されたレベルより上位レベルのログを表示する、という挙動になっています。
ログレベル指定のないログを非表示にするには
ところで、上の例だとMinLevelを最上位レベル(上の例なら"ERROR"
)にしてもログレベル指定のないログ(上の例なら4つめのPrint("Message I haven't updated")
)は表示されてしまいます。これを抑制する方法はないのでしょうか。
実は、ログレベルの指定がないログはログレベル""
として扱われます1。ですから、Levels
で""
の優先順位を指定すれば簡単に抑制できます。
たとえば次のようにすればログレベル指定がないログは表示されません。
package main
import (
"log"
"os"
"github.com/hashicorp/logutils"
)
func main() {
filter := &logutils.LevelFilter{
Levels: []logutils.LogLevel{"", "DEBUG", "WARN", "ERROR"},
MinLevel: logutils.LogLevel("WARN"),
Writer: os.Stderr,
}
log.SetOutput(filter)
log.Print("[DEBUG] Debugging") // 表示されない
log.Print("[WARN] Warning") // 表示される
log.Print("[ERROR] Erring") // 表示される
log.Print("Message I haven't updated") // 表示されない
}
これは標準パッケージlog
で作り始めてしまってログレベル指定がないログが大量にあるような場合に便利でしょう。
未知のログレベルが指定された場合にこれを抑制する方法はない
ちなみに、Levels
に含まれないログレベルが指定された場合、そのログは必ず出力されます。上の例ならlog.Print("[INFO] info")
はMinLevel
の指定が何だろうと必ず表示されます。これは状況によっては不便かもしれません。
参考記事
-
ソースコードを読んだらそうなっていたというだけで、仕様かどうかは疑問です。 ↩