# README
logger
Gin middleware/handler to log URL paths using rs/zerolog.
Example
package main
import (
"fmt"
"net/http"
"regexp"
"time"
"github.com/gin-contrib/logger"
"github.com/gin-contrib/requestid"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
var rxURL = regexp.MustCompile(`^/regexp\d*`)
func main() {
r := gin.New()
// Add a logger middleware, which:
// - Logs all requests, like a combined access and error log.
// - Logs to stdout.
// r.Use(logger.SetLogger())
// Example pong request.
r.GET("/pong", logger.SetLogger(), func(c *gin.Context) {
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example ping request.
r.GET("/ping", logger.SetLogger(
logger.WithSkipPath([]string{"/skip"}),
logger.WithUTC(true),
logger.WithSkipPathRegexps(rxURL),
), func(c *gin.Context) {
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example skip path request.
r.GET("/skip", logger.SetLogger(
logger.WithSkipPath([]string{"/skip"}),
), func(c *gin.Context) {
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example skip path request.
r.GET("/regexp1", logger.SetLogger(
logger.WithSkipPathRegexps(rxURL),
), func(c *gin.Context) {
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example skip path request.
r.GET("/regexp2", logger.SetLogger(
logger.WithSkipPathRegexps(rxURL),
), func(c *gin.Context) {
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})
// add custom fields.
r.GET("/id", requestid.New(requestid.WithGenerator(func() string {
return "foobar"
})), logger.SetLogger(
logger.WithLogger(func(c *gin.Context, l zerolog.Logger) zerolog.Logger {
if trace.SpanFromContext(c.Request.Context()).SpanContext().IsValid() {
l = l.With().
Str("trace_id", trace.SpanFromContext(c.Request.Context()).SpanContext().TraceID().String()).
Str("span_id", trace.SpanFromContext(c.Request.Context()).SpanContext().SpanID().String()).
Logger()
}
return l.With().
Str("id", requestid.Get(c)).
Str("foo", "bar").
Str("path", c.Request.URL.Path).
Logger()
}),
), func(c *gin.Context) {
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example of JSON format log
r.GET("/json", logger.SetLogger(
logger.WithLogger(func(_ *gin.Context, l zerolog.Logger) zerolog.Logger {
return l.Output(gin.DefaultWriter).With().Logger()
}),
), func(c *gin.Context) {
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example of logging data on gin.Context
r.GET("/context", logger.SetLogger(
logger.WithContext(func(c *gin.Context, e *zerolog.Event) *zerolog.Event {
return e.Any("data1", c.MustGet("data1")).Any("data2", c.MustGet("data2"))
}),
), func(c *gin.Context) {
c.Set("data1", rand.Intn(100))
c.Set("data2", rand.Intn(100))
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()))
})
// Example of skipper usage
v1 := r.Group("/v1", logger.SetLogger(
logger.WithSkipper(func(c *gin.Context) bool {
return c.Request.Method == "GET"
})))
{
v1.GET("/ping", func(c *gin.Context) {
c.String(http.StatusOK, "pong01 "+fmt.Sprint(time.Now().Unix()))
})
v1.POST("/ping", func(c *gin.Context) {
c.String(http.StatusOK, "pong02 "+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")
}
}
Screenshot
Run app server:
go run _example/main.go
Test request:
curl http://localhost:8080/ping
curl http://localhost:8080/pong
curl http://localhost:8080/json
# Functions
Get retrieves the zerolog.Logger instance from the given gin.Context.
ParseLevel parses a string representation of a log level and returns the corresponding zerolog.Level.
SetLogger returns a gin.HandlerFunc (middleware) that logs requests using zerolog.
WithClientErrorLevel set the log level used for request with status code between 400 and 499.
WithContext is an option for configuring the logger with a custom context function.
WithDefaultLevel set the log level used for request with status code < 400.
WithLogger returns an Option that sets the logger function in the config.
WithPathLevel use logging level for successful requests to a specific path.
WithServerErrorLevel sets the logging level for server errors.
WithSkipPath skip URL path by specific pattern.
WithSkipPathRegexps returns an Option that sets the skipPathRegexps field in the config.
WithSkipper returns an Option that sets the Skipper function in the config.
WithUTC returns an Option that sets the utc field in the config.
WithWriter change the default output writer.
# Interfaces
Option is an interface that defines a method to apply a configuration to a given config instance.