feat(logger): Add CustomFormat option

This commit introduces a `CustomFormat` option to the `Config` struct, allowing users to specify a predefined format (like "common", "combined", "json", or "ecs")
pull/3359/head
edvardsanta 2025-03-20 23:36:20 -03:00
parent edc011a087
commit 7136389e58
4 changed files with 21 additions and 17 deletions

View File

@ -57,14 +57,18 @@ type Config struct {
// The full list of available placeholders can be found in 'tags.go' or at
// 'https://docs.gofiber.io/api/middleware/logger/#constants'.
//
// Alternatively, you can use one of the predefined formats:
// If no format is specified, the default format is used: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}"
// If both `Format` and `CustomFormat` are provided, the `CustomFormat` will be used, and the `Format` field will be ignored.
Format string
// You can use one of the predefined formats:
// - "default" → Uses the default log format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}"
// - "common" → Uses the Common Log Format (CLF): "${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent}"
// - "combined" → Uses the Combined Log Format: "${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent} "${referer}" "${ua}""
// - "json" → Uses the JSON structured log format: "{"time":"${time}","ip":"${ip}","method":"${method}","url":"${url}","status":${status},"bytesSent":${bytesSent}}"
//
// If no format is specified, the default format is used: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}"
Format string
// - "ecs" → Uses the Elastic Common Schema (ECS) log format: "{"@timestamp":"${time}","ecs":{"version":"1.6.0"},"client":{"ip":"${ip}"},"http":{"request":{"method":"${method}","url":"${url}","protocol":"${protocol}"},"response":{"status_code":${status},"body":{"bytes":${bytesSent}}}}, "log":{"level":"INFO","logger":"fiber"},"message":"${method} ${url} responded with ${status}"}"
// If both `Format` and `CustomFormat` are provided, the `CustomFormat` will be used, and the `Format` field will be ignored.
CustomFormat string
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
//

View File

@ -1,15 +1,15 @@
package logger
const (
// Fiber's default logger `
// Fiber's default logger
FormatDefault = "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n"
// Common log format
// Apache Common Log Format (CLF)
FormatCommonLog = "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent}\n"
// Combined log format
// Apache Combined Log Format
FormatCombined = "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent} \"${referer}\" \"${ua}\"\n"
// JSON log formats
FormatJSON = "{\"time\":\"${time}\",\"ip\":\"${ip}\",\"method\":\"${method}\",\"url\":\"${url}\",\"status\":${status},\"bytesSent\":${bytesSent}}\n"
// ECS Log format
// Elastic Common Schema (ECS) Log Format
FormatECS = "{\"@timestamp\":\"${time}\",\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":\"${ip}\"},\"http\":{\"request\":{\"method\":\"${method}\",\"url\":\"${url}\",\"protocol\":\"${protocol}\"},\"response\":{\"status_code\":${status},\"body\":{\"bytes\":${bytesSent}}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":\"${method} ${url} responded with ${status}\"}\n"
)

View File

@ -31,7 +31,7 @@ func New(config ...Config) fiber.Handler {
// Create correct timeformat
timestamp.Store(time.Now().In(cfg.timeZoneLocation).Format(cfg.TimeFormat))
if logFormat, exists := LoggerConfig[cfg.Format]; exists {
if logFormat, exists := LoggerConfig[cfg.CustomFormat]; exists {
cfg.Format = logFormat
}

View File

@ -475,8 +475,8 @@ func Test_Logger_CLF_Format_With_Name(t *testing.T) {
app := fiber.New()
app.Use(New(Config{
Format: "common",
Stream: buf,
CustomFormat: "common",
Stream: buf,
}))
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil))
@ -525,8 +525,8 @@ func Test_Logger_Combined_CLF_Format_With_Name(t *testing.T) {
app := fiber.New()
app.Use(New(Config{
Format: "combined",
Stream: buf,
CustomFormat: "combined",
Stream: buf,
}))
const expectedUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
const expectedReferer = "http://example.com"
@ -587,8 +587,8 @@ func Test_Logger_Json_Format_With_Name(t *testing.T) {
app := fiber.New()
app.Use(New(Config{
Format: "json",
Stream: buf,
CustomFormat: "json",
Stream: buf,
}))
req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)
@ -647,8 +647,8 @@ func Test_Logger_ECS_Format_With_Name(t *testing.T) {
app := fiber.New()
app.Use(New(Config{
Format: "ecs",
Stream: buf,
CustomFormat: "ecs",
Stream: buf,
}))
req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)