diff --git a/README.md b/README.md index 5c09c7a..fd36b27 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,15 @@ func main() { c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix())) }) + // Example of skipper usage + r.GET("/health", logger.SetLogger( + logger.WithSkipper(func(c *gin.Context) bool { + return c.Request.URL.Path == "/health" + }), + ), func(c *gin.Context) { + c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix())) + }) + // Listen and Server in 0.0.0.0:8080 if err := r.Run(":8080"); err != nil { log.Fatal().Msg("can' start server with 8080 port") diff --git a/logger.go b/logger.go index 41cd195..8d1dca5 100644 --- a/logger.go +++ b/logger.go @@ -14,6 +14,9 @@ import ( type Fn func(*gin.Context, zerolog.Logger) zerolog.Logger +// Skipper is a function to skip logs based on provided Context +type Skipper func(c *gin.Context) bool + // Config defines the config for logger middleware type config struct { logger Fn @@ -21,6 +24,9 @@ type config struct { utc bool skipPath []string skipPathRegexps []*regexp.Regexp + // skip is a Skipper that indicates which logs should not be written. + // Optional. + skip Skipper // Output is a writer where logs are written. // Optional. Default value is gin.DefaultWriter. output io.Writer @@ -84,7 +90,7 @@ func SetLogger(opts ...Option) gin.HandlerFunc { c.Next() track := true - if _, ok := skip[path]; ok { + if _, ok := skip[path]; ok || (cfg.skip != nil && cfg.skip(c)) { track = false } @@ -112,7 +118,9 @@ func SetLogger(opts ...Option) gin.HandlerFunc { Str("path", path). Str("ip", c.ClientIP()). Dur("latency", latency). - Str("user_agent", c.Request.UserAgent()).Logger() + Str("user_agent", c.Request.UserAgent()). + Int("body_size", c.Writer.Size()). + Logger() msg := "Request" if len(c.Errors) > 0 { diff --git a/logger_test.go b/logger_test.go index 53bfb0d..e43d8c8 100644 --- a/logger_test.go +++ b/logger_test.go @@ -226,6 +226,29 @@ func TestLoggerCustomLevel(t *testing.T) { assert.Contains(t, buffer.String(), "FTL") } +func TestLoggerSkipper(t *testing.T) { + buffer := new(bytes.Buffer) + gin.SetMode(gin.ReleaseMode) + r := gin.New() + r.Use(SetLogger( + WithWriter(buffer), + WithSkipper(func(c *gin.Context) bool { + return c.Request.URL.Path == "/example2" + }), + )) + r.GET("/example", func(c *gin.Context) {}) + r.GET("/example2", func(c *gin.Context) {}) + + performRequest(r, "GET", "/example") + assert.Contains(t, buffer.String(), "GET") + assert.Contains(t, buffer.String(), "/example") + + buffer.Reset() + performRequest(r, "GET", "/example2") + assert.NotContains(t, buffer.String(), "GET") + assert.NotContains(t, buffer.String(), "/example2") +} + func BenchmarkLogger(b *testing.B) { gin.SetMode(gin.ReleaseMode) r := gin.New() diff --git a/options.go b/options.go index ac7c0b4..e426f98 100644 --- a/options.go +++ b/options.go @@ -88,3 +88,12 @@ func WithServerErrorLevel(lvl zerolog.Level) Option { c.serverErrorLevel = lvl }) } + +// WithSkipper set function to skip middleware +// requests with this function returning true will not have their logs written +// Default is nil +func WithSkipper(s Skipper) Option { + return optionFunc(func(c *config) { + c.skip = s + }) +}