From cc550f93c497e07f3506f0fc8b4a65e4ee5cba37 Mon Sep 17 00:00:00 2001 From: Skyenought <1808644906@qq.com> Date: Wed, 23 Aug 2023 04:47:43 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20logger/middleware=20to?= =?UTF-8?q?=20Eliminate=20Code=20Duplication?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middleware/logger/logger.go | 49 ++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/middleware/logger/logger.go b/middleware/logger/logger.go index f33f3562a3..7ae0e1e95b 100644 --- a/middleware/logger/logger.go +++ b/middleware/logger/logger.go @@ -139,40 +139,33 @@ func New(config ...Config) fiber.Handler { // Default output when no custom Format or io.Writer is given if cfg.Format == ConfigDefault.Format { - // Format error if exist + // Format error if it exists formatErr := "" - if cfg.enableColors { - if chainErr != nil { + if chainErr != nil { + if cfg.enableColors { formatErr = colors.Red + " | " + chainErr.Error() + colors.Reset - } - _, _ = buf.WriteString( //nolint:errcheck // This will never fail - fmt.Sprintf("%s |%s %3d %s| %13v | %15s |%s %-7s %s| %-"+errPaddingStr+"s %s\n", - timestamp.Load().(string), - statusColor(c.Response().StatusCode(), colors), c.Response().StatusCode(), colors.Reset, - data.Stop.Sub(data.Start), - c.IP(), - methodColor(c.Method(), colors), c.Method(), colors.Reset, - c.Path(), - formatErr, - ), - ) - } else { - if chainErr != nil { + } else { formatErr = " | " + chainErr.Error() } - _, _ = buf.WriteString( //nolint:errcheck // This will never fail - fmt.Sprintf("%s | %3d | %13v | %15s | %-7s | %-"+errPaddingStr+"s %s\n", - timestamp.Load().(string), - c.Response().StatusCode(), - data.Stop.Sub(data.Start), - c.IP(), - c.Method(), - c.Path(), - formatErr, - ), - ) } + // Construct the log format + logFormat := "%s |%s %3d %s| %7v | %15s |%s %-7s %s| %-" + errPaddingStr + "s %s\n" + if !cfg.enableColors { + logFormat = "%s | %3d | %7v | %15s | %-7s | %-" + errPaddingStr + "s %s\n" + } + + // Write log entry to buffer + _, _ = buf.WriteString(fmt.Sprintf(logFormat, + timestamp.Load().(string), + statusColor(c.Response().StatusCode(), colors), c.Response().StatusCode(), colors.Reset, + data.Stop.Sub(data.Start).Round(time.Millisecond), + c.IP(), + methodColor(c.Method(), colors), c.Method(), colors.Reset, + c.Path(), + formatErr, + )) //nolint:errcheck // This will never fail + // Write buffer to output _, _ = cfg.Output.Write(buf.Bytes()) //nolint:errcheck // This will never fail From 8117e715efb8ef3aa9d792ef8e0c8bb6f93beea0 Mon Sep 17 00:00:00 2001 From: Skyenought <1808644906@qq.com> Date: Thu, 24 Aug 2023 22:11:07 +0800 Subject: [PATCH 2/2] update defaultformat --- docs/api/middleware/logger.md | 30 +++++++++++++++--------------- middleware/logger/config.go | 4 ++-- middleware/logger/logger.go | 24 +++++++++++++++--------- middleware/logger/tags.go | 5 +++++ 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/docs/api/middleware/logger.md b/docs/api/middleware/logger.md index a01e9bd54c..94931d7087 100644 --- a/docs/api/middleware/logger.md +++ b/docs/api/middleware/logger.md @@ -92,27 +92,27 @@ app.Use(logger.New(logger.Config{ ### Config -| Property | Type | Description | Default | -|:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------| -| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Done | `func(*fiber.Ctx, []byte)` | Done is a function that is called after the log string for a request is written to Output, and pass the log string as parameter. | `nil` | -| CustomTags | `map[string]LogFunc` | tagFunctions defines the custom tag action. | `map[string]LogFunc` | -| Format | `string` | Format defines the logging tags. | `[${time}] ${status} - ${latency} ${method} ${path}\n` | -| TimeFormat | `string` | TimeFormat defines the time format for log timestamps. | `15:04:05` | -| TimeZone | `string` | TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc | `"Local"` | -| TimeInterval | `time.Duration` | TimeInterval is the delay before the timestamp is updated. | `500 * time.Millisecond` | -| Output | `io.Writer` | Output is a writer where logs are written. | `os.Stdout` | -| DisableColors | `bool` | DisableColors defines if the logs output should be colorized. | `false` | -| enableColors | `bool` | Internal field for enabling colors in the log output. (This is not a user-configurable field) | - | -| enableLatency | `bool` | Internal field for enabling latency measurement in logs. (This is not a user-configurable field) | - | -| timeZoneLocation | `*time.Location` | Internal field for the time zone location. (This is not a user-configurable field) | - | +| Property | Type | Description | Default | +| :--------------- | :------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | +| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | +| Done | `func(*fiber.Ctx, []byte)` | Done is a function that is called after the log string for a request is written to Output, and pass the log string as parameter. | `nil` | +| CustomTags | `map[string]LogFunc` | tagFunctions defines the custom tag action. | `map[string]LogFunc` | +| Format | `string` | Format defines the logging tags. | `${time} | ${status} | ${latency} | ${method} | ${path} | ${error}\n` | +| TimeFormat | `string` | TimeFormat defines the time format for log timestamps. | `15:04:05` | +| TimeZone | `string` | TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc | `"Local"` | +| TimeInterval | `time.Duration` | TimeInterval is the delay before the timestamp is updated. | `500 * time.Millisecond` | +| Output | `io.Writer` | Output is a writer where logs are written. | `os.Stdout` | +| DisableColors | `bool` | DisableColors defines if the logs output should be colorized. | `false` | +| enableColors | `bool` | Internal field for enabling colors in the log output. (This is not a user-configurable field) | - | +| enableLatency | `bool` | Internal field for enabling latency measurement in logs. (This is not a user-configurable field) | - | +| timeZoneLocation | `*time.Location` | Internal field for the time zone location. (This is not a user-configurable field) | - | ## Default Config ```go var ConfigDefault = Config{ Next: nil, Done: nil, - Format: "[${time}] ${status} - ${latency} ${method} ${path}\n", + Format: "${time} | ${status} | ${latency} | ${method} | ${path} | ${error}\n", TimeFormat: "15:04:05", TimeZone: "Local", TimeInterval: 500 * time.Millisecond, diff --git a/middleware/logger/config.go b/middleware/logger/config.go index 5b91a065ee..edc6c2bd99 100644 --- a/middleware/logger/config.go +++ b/middleware/logger/config.go @@ -28,7 +28,7 @@ type Config struct { // Format defines the logging tags // - // Optional. Default: [${time}] ${status} - ${latency} ${method} ${path}\n + // Optional. Default: ${time} | ${status} | ${latency} | ${method} | ${path} | ${error}\n Format string // TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html @@ -86,7 +86,7 @@ type LogFunc func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (i var ConfigDefault = Config{ Next: nil, Done: nil, - Format: "[${time}] ${status} - ${latency} ${method} ${path}\n", + Format: "${time} | ${status} | ${latency} | ${method} | ${path} | ${error}\n", TimeFormat: "15:04:05", TimeZone: "Local", TimeInterval: 500 * time.Millisecond, diff --git a/middleware/logger/logger.go b/middleware/logger/logger.go index 7ae0e1e95b..1c59d921de 100644 --- a/middleware/logger/logger.go +++ b/middleware/logger/logger.go @@ -58,6 +58,10 @@ func New(config ...Config) fiber.Handler { errHandler fiber.ErrorHandler dataPool = sync.Pool{New: func() interface{} { return new(Data) }} + + methodColorFmt string + statusCodeFmt string + colorReset string ) // If colors are enabled, check terminal compatibility @@ -151,20 +155,22 @@ func New(config ...Config) fiber.Handler { // Construct the log format logFormat := "%s |%s %3d %s| %7v | %15s |%s %-7s %s| %-" + errPaddingStr + "s %s\n" - if !cfg.enableColors { - logFormat = "%s | %3d | %7v | %15s | %-7s | %-" + errPaddingStr + "s %s\n" - } - // Write log entry to buffer - _, _ = buf.WriteString(fmt.Sprintf(logFormat, + if cfg.enableColors { + colorReset = colors.Reset + statusCodeFmt = statusColor(c.Response().StatusCode(), colors) + methodColorFmt = methodColor(c.Method(), colors) + } + _, _ = buf.WriteString(fmt.Sprintf( //nolint:errcheck // This will never fail + logFormat, timestamp.Load().(string), - statusColor(c.Response().StatusCode(), colors), c.Response().StatusCode(), colors.Reset, - data.Stop.Sub(data.Start).Round(time.Millisecond), + statusCodeFmt, c.Response().StatusCode(), colorReset, + data.Stop.Sub(data.Start), c.IP(), - methodColor(c.Method(), colors), c.Method(), colors.Reset, + methodColorFmt, c.Method(), colorReset, c.Path(), formatErr, - )) //nolint:errcheck // This will never fail + )) // Write buffer to output _, _ = cfg.Output.Write(buf.Bytes()) //nolint:errcheck // This will never fail diff --git a/middleware/logger/tags.go b/middleware/logger/tags.go index af114a5777..3f10905d37 100644 --- a/middleware/logger/tags.go +++ b/middleware/logger/tags.go @@ -139,6 +139,11 @@ func createTagMap(cfg *Config) map[string]LogFunc { }, TagError: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) { if data.ChainErr != nil { + if cfg.enableColors { + colors := c.App().Config().ColorScheme + return output.WriteString(fmt.Sprintf("%s %s %s", colors.Red, data.ChainErr.Error(), colors.Reset)) + } + return output.WriteString(data.ChainErr.Error()) } return output.WriteString("-")