はじめに
health_checkのログが多すぎて大事なログが見つけられない...みたいなことありますよね。
Ginの環境を作っている際にその問題にぶち当たったので、そんなお悩みを解決できる方法を備忘録としてまとめました。
結論
以下の2通りの方法で、特定のパス(ここでは/health)についてログ出力を抑制することができます。
router := gin.New()
router.Use(gin.LoggerWithWriter(gin.DefaultWriter, "/health"))
router.Use(gin.Recovery())
router := gin.New()
router.Use(gin.LoggerWithConfig(gin.LoggerConfig{SkipPaths: []string{"/health"}}))
router.Use(gin.Recovery())
通常、基本的なルーターの設定にはgin.Default()を使用することが多いと思います。
この関数はデフォルトでLogger
とRecovery
のミドルウェアを設定します。
package gin
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default(opts ...OptionFunc) *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine.With(opts...)
}
しかし、この関数で設定されるLogger
ミドルウェアは設定の変更ができず、特定のパスに対してログ出力を抑制することができません。
そのため、gin.Default()
ではなく、gin.New()
を使用し、手動でログ設定を追加する(gin.LoggerWithWriter
or gin.LoggerWithConfig
)必要があります。
gin.New()を使用する場合、gin.Recovery()
の設定を忘れると、500エラーが発生した際にGinがクラッシュしてしまうことがあります。避けたい場合はgin.Recovery()
も設定しましょう。
LoggerWithWriter
とLoggerWithConfig
について
どちらを使うのが適当かは正直よくわかってません。
ただし、コードを見てみると、LoggerWithWriter
の内部でLoggerWithConfig
を呼び出しており、引数で明確にnotlogged
を受け取れるようになっています。
そのため、シンプルにログ出力を制御したい場合は、LoggerWithWriter
を使用する方が無難なのかなと思っています。
package gin
// LoggerWithWriter instance a Logger middleware with the specified writer buffer.
// Example: os.Stdout, a file opened in write mode, a socket...
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
return LoggerWithConfig(LoggerConfig{
Output: out,
SkipPaths: notlogged,
})
}