logger

package module
v1.2.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2025 License: MIT Imports: 8 Imported by: 189

README

logger

Run Tests codecov Go Report Card GoDoc

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

screenshot

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Get added in v1.2.0

func Get(c *gin.Context) zerolog.Logger

GetLogger retrieves the zerolog.Logger instance from the given gin.Context. It assumes that the logger has been previously set in the context with the key loggerKey. If the logger is not found, it will panic.

Parameters:

c - the gin.Context from which to retrieve the logger.

Returns:

zerolog.Logger - the logger instance stored in the context.

func ParseLevel added in v0.2.6

func ParseLevel(levelStr string) (zerolog.Level, error)

ParseLevel parses a string representation of a log level and returns the corresponding zerolog.Level. It takes a single argument:

  • levelStr: a string representing the log level (e.g., "debug", "info", "warn", "error").

It returns:

  • zerolog.Level: the parsed log level.
  • error: an error if the log level string is invalid.

func SetLogger

func SetLogger(opts ...Option) gin.HandlerFunc

SetLogger returns a gin.HandlerFunc (middleware) that logs requests using zerolog. It accepts a variadic number of Option functions to customize the logger's behavior.

The logger configuration includes:

  • defaultLevel: the default logging level (default: zerolog.InfoLevel).
  • clientErrorLevel: the logging level for client errors (default: zerolog.WarnLevel).
  • serverErrorLevel: the logging level for server errors (default: zerolog.ErrorLevel).
  • output: the output writer for the logger (default: gin.DefaultWriter).
  • skipPath: a list of paths to skip logging.
  • skipPathRegexps: a list of regular expressions to skip logging for matching paths.
  • logger: a custom logger function to use instead of the default logger.

The middleware logs the following request details:

  • method: the HTTP method of the request.
  • path: the URL path of the request.
  • ip: the client's IP address.
  • user_agent: the User-Agent header of the request.
  • status: the HTTP status code of the response.
  • latency: the time taken to process the request.
  • body_size: the size of the response body.

The logging level for each request is determined based on the response status code:

  • clientErrorLevel for 4xx status codes.
  • serverErrorLevel for 5xx status codes.
  • defaultLevel for other status codes.
  • Custom levels can be set for specific paths using the pathLevels configuration.

Types

type EventFn added in v1.2.2

type EventFn func(*gin.Context, *zerolog.Event) *zerolog.Event

EventFn is a function type that takes a gin.Context and a zerolog.Event as parameters, and returns a zerolog.Event. It is typically used to modify or enhance the event within the context of a Gin HTTP request.

type Fn added in v0.2.4

Fn is a function type that takes a gin.Context and a zerolog.Logger as parameters, and returns a zerolog.Logger. It is typically used to modify or enhance the logger within the context of a Gin HTTP request.

type Option added in v0.1.0

type Option interface {
	// contains filtered or unexported methods
}

Option is an interface that defines a method to apply a configuration to a given config instance. Implementations of this interface can be used to modify the configuration settings of the logger.

func WithClientErrorLevel added in v0.2.2

func WithClientErrorLevel(lvl zerolog.Level) Option

WithClientErrorLevel returns an Option that sets the clientErrorLevel field in the config. The clientErrorLevel field specifies the logging level for requests with status codes between 400 and 499.

Parameters:

lvl - The logging level to be used for requests with status codes between 400 and 499.

Returns:

Option - An option that sets the clientErrorLevel field in the config.

func WithContext added in v1.2.2

func WithContext(fn func(*gin.Context, *zerolog.Event) *zerolog.Event) Option

WithContext returns an Option that sets the context field in the config. The context field is a function that takes a *gin.Context and a *zerolog.Event, and returns a modified *zerolog.Event. This allows for custom logging behavior based on the request context.

Parameters:

fn - A function that takes a *gin.Context and a *zerolog.Event, and returns a modified *zerolog.Event.

Returns:

Option - An option that sets the context field in the config.

func WithDefaultLevel added in v0.2.2

func WithDefaultLevel(lvl zerolog.Level) Option

WithDefaultLevel returns an Option that sets the defaultLevel field in the config. The defaultLevel field specifies the logging level for requests with status codes less than 400.

Parameters:

lvl - The logging level to be used for requests with status codes less than 400.

Returns:

Option - An option that sets the defaultLevel field in the config.

func WithLogger added in v0.1.0

func WithLogger(fn func(*gin.Context, zerolog.Logger) zerolog.Logger) Option

WithLogger returns an Option that sets the logger function in the config. The logger function is a function that takes a *gin.Context and a zerolog.Logger, and returns a zerolog.Logger. This function is typically used to modify or enhance the logger within the context of a Gin HTTP request.

Parameters:

fn - A function that takes a *gin.Context and a zerolog.Logger, and returns a zerolog.Logger.

Returns:

Option - An option that sets the logger function in the config.

func WithMessage added in v1.2.4

func WithMessage(message string) Option

WithMessage returns an Option that sets the message field in the config. The message field specifies a custom log message to be used when an HTTP request has finished and is logged.

Parameters:

message - The custom log message.

Returns:

Option - An option that sets the message field in the config.

func WithPathLevel added in v1.0.0

func WithPathLevel(m map[string]zerolog.Level) Option

WithPathLevel returns an Option that sets the pathLevels field in the config. The pathLevels field is a map that associates specific URL paths with logging levels.

Parameters:

m - A map where the keys are URL paths and the values are zerolog.Level.

Returns:

Option - An option that sets the pathLevels field in the config.

func WithServerErrorLevel added in v0.2.2

func WithServerErrorLevel(lvl zerolog.Level) Option

WithServerErrorLevel returns an Option that sets the serverErrorLevel field in the config. The serverErrorLevel field specifies the logging level for server errors.

Parameters:

lvl - The logging level to be used for server errors.

Returns:

Option - An option that sets the serverErrorLevel field in the config.

func WithSkipPath added in v0.1.0

func WithSkipPath(s []string) Option

WithSkipPath returns an Option that sets the skipPath field in the config. The skipPath field is a list of URL paths to be skipped from logging.

Parameters:

s - A list of URL paths to be skipped from logging.

Returns:

Option - An option that sets the skipPath field in the config.

func WithSkipPathRegexps added in v0.3.0

func WithSkipPathRegexps(regs ...*regexp.Regexp) Option

WithSkipPathRegexps returns an Option that sets the skipPathRegexps field in the config. The skipPathRegexps field is a list of regular expressions that match paths to be skipped from logging.

Parameters:

regs - A list of regular expressions to match paths to be skipped from logging.

Returns:

Option - An option that sets the skipPathRegexps field in the config.

func WithSkipper added in v1.0.0

func WithSkipper(s Skipper) Option

WithSkipper returns an Option that sets the Skipper function in the config. The Skipper function determines whether a request should be skipped for logging.

Parameters:

s - A function that takes a gin.Context and returns a boolean indicating whether the request should be skipped.

Returns:

Option - An option that sets the Skipper function in the config.

func WithSpecificLogLevelByStatusCode added in v1.2.5

func WithSpecificLogLevelByStatusCode(statusCodes map[int]zerolog.Level) Option

WithSpecificLogLevelByStatusCode returns an Option that sets the specificLevelByStatusCode field in the config. The specificLevelByStatusCode field is a map that associates specific HTTP status codes with logging levels.

Parameters:

statusCodes - A map where the keys are HTTP status codes and the values are zerolog.Level.

Returns:

Option - An option that sets the specificLevelByStatusCode field in the config.

func WithUTC added in v0.1.0

func WithUTC(s bool) Option

WithUTC returns an Option that sets the utc field in the config. The utc field is a boolean that indicates whether to use UTC time zone or local time zone.

Parameters:

s - A boolean indicating whether to use UTC time zone.

Returns:

Option - An option that sets the utc field in the config.

func WithWriter added in v0.2.0

func WithWriter(s io.Writer) Option

WithWriter returns an Option that sets the output field in the config. The output field is an io.Writer that specifies the destination for log output.

Parameters:

s - The writer to be used for log output.

Returns:

Option - An option that sets the output field in the config.

type Skipper added in v1.0.0

type Skipper func(c *gin.Context) bool

Skipper defines a function to skip middleware. It takes a gin.Context as input and returns a boolean indicating whether to skip the middleware for the given context.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL