Skip to content

Make log level configurable with Logger Middleware for any logs #1989

@ymotongpoo

Description

@ymotongpoo

Issue Description

As of today, Logger Middleware does not support log level in the custom logger format. This makes all access logs being without log levels.

#1649 is relevant to this issue.

Quoting all available tags for Logger Middleware from the doc:

// LoggerConfig defines the config for Logger middleware.
LoggerConfig struct {
  // Skipper defines a function to skip middleware.
  Skipper Skipper

  // Tags to construct the logger format.
  //
  // - time_unix
  // - time_unix_nano
  // - time_rfc3339
  // - time_rfc3339_nano
  // - time_custom
  // - id (Request ID)
  // - remote_ip
  // - uri
  // - host
  // - method
  // - path
  // - protocol
  // - referer
  // - user_agent
  // - status
  // - error
  // - latency (In nanoseconds)
  // - latency_human (Human readable)
  // - bytes_in (Bytes received)
  // - bytes_out (Bytes sent)
  // - header:<NAME>
  // - query:<NAME>
  // - form:<NAME>
  //
  // Example "${remote_ip} ${status}"
  //
  // Optional. Default value DefaultLoggerConfig.Format.
  Format string `yaml:"format"`

  // Optional. Default value DefaultLoggerConfig.CustomTimeFormat.
  CustomTimeFormat string `yaml:"custom_time_format"`

  // Output is a writer where logs in JSON format are written.
  // Optional. Default value os.Stdout.
  Output io.Writer
}

Checklist

  • Dependencies installed
  • No typos
  • Searched existing issues and docs

Expected behaviour

level tag is available in the LoggerConfig#Format.

Actual behaviour

level tag is not available. I tried it just in case and I confirmed it doesn't work.

Steps to reproduce

I added "severity": "${level}" to the DefaultLoggerConfig.Format and used that format in CustomConfig, then I called LoggerMiddleware like this:

e.Use(middleware.LoggerWithConfig(CustomConfig))

Then launched the app and accessed to the server. The output of the access log is as the following:

{"severity":"", "time":"2021-09-17T11:51:30.18712593+09:00","id":"","remote_ip":"::1","host":"localhost:1323","method":"GET","uri":"/","user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36","status":200,"error":"","latency":53214,"latency_human":"53.214µs","bytes_in":0,"bytes_out":13}

As you see, because ${level} is not available, it just generates blank strings.

Working code to debug

package main

import (
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
)

var CustomConfig = middleware.LoggerConfig{
	Format: `{"severity":"${level}", "time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}",` +
		`"host":"${host}","method":"${method}","uri":"${uri}","user_agent":"${user_agent}",` +
		`"status":${status},"error":"${error}","latency":${latency},"latency_human":"${latency_human}"` +
		`,"bytes_in":${bytes_in},"bytes_out":${bytes_out}}` + "\n",
}

func main() {
	e := echo.New()
	e.Debug = true
	e.Logger.SetLevel(0)

	// Middleware
	e.Use(middleware.LoggerWithConfig(CustomConfig))

	// Routes
	e.GET("/", func(c echo.Context) error {
		e.Logger.Info("access")
		return c.String(200, "Hello, World!")
	})

	// Start server
	e.Logger.Fatal(e.Start(":1323"))
}

Version/commit

v4.5.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions