Skip to content

Commit

Permalink
🚀 Add DisableColors to set the default output format (#2493)
Browse files Browse the repository at this point in the history
Add DisableColor for default logger format
  • Loading branch information
Skyenought committed Jun 5, 2023
1 parent c955d76 commit 06ef450
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 78 deletions.
100 changes: 55 additions & 45 deletions docs/api/middleware/logger.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,56 +80,66 @@ app.Use(logger.New(logger.Config{
}
},
}))

// Disable colors when outputting to default format
app.Use(logger.New(logger.Config{
DisableColors: true,
}))
```

## Config
```go
// Config defines the config for middleware.
type Config struct {
// Next defines a function to skip this middleware when returned true.
//
// Optional. Default: nil
Next func(c *fiber.Ctx) bool

// 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.
//
// Optional. Default: nil
Done func(c *fiber.Ctx, logString []byte)

// tagFunctions defines the custom tag action
//
// Optional. Default: map[string]LogFunc
CustomTags map[string]LogFunc

// Format defines the logging tags
//
// Optional. Default: [${time}] ${status} - ${latency} ${method} ${path}\n
Format string

// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
//
// Optional. Default: 15:04:05
TimeFormat string

// TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc
//
// Optional. Default: "Local"
TimeZone string

// TimeInterval is the delay before the timestamp is updated
//
// Optional. Default: 500 * time.Millisecond
TimeInterval time.Duration

// Output is a writer where logs are written
//
// Default: os.Stdout
Output io.Writer

enableColors bool
enableLatency bool
timeZoneLocation *time.Location
// Next defines a function to skip this middleware when returned true.
//
// Optional. Default: nil
Next func(c *fiber.Ctx) bool

// 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.
//
// Optional. Default: nil
Done func(c *fiber.Ctx, logString []byte)

// tagFunctions defines the custom tag action
//
// Optional. Default: map[string]LogFunc
CustomTags map[string]LogFunc

// Format defines the logging tags
//
// Optional. Default: [${time}] ${status} - ${latency} ${method} ${path}\n
Format string

// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
//
// Optional. Default: 15:04:05
TimeFormat string

// TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc
//
// Optional. Default: "Local"
TimeZone string

// TimeInterval is the delay before the timestamp is updated
//
// Optional. Default: 500 * time.Millisecond
TimeInterval time.Duration

// Output is a writer where logs are written
//
// Default: os.Stdout
Output io.Writer

// DisableColors defines if the logs output should be colorized
//
// Default: false
DisableColors bool

enableColors bool
enableLatency bool
timeZoneLocation *time.Location
}
type LogFunc func(buf logger.Buffer, c *fiber.Ctx, data *logger.Data, extraParam string) (int, error)
```
Expand All @@ -143,7 +153,7 @@ var ConfigDefault = Config{
TimeZone: "Local",
TimeInterval: 500 * time.Millisecond,
Output: os.Stdout,
enableColors: true,
DisableColors: true,
}
```

Expand Down
23 changes: 7 additions & 16 deletions middleware/logger/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package logger
import (
"io"
"os"
"strings"
"time"

"github.com/gofiber/fiber/v2"
Expand Down Expand Up @@ -52,6 +51,11 @@ type Config struct {
// Default: os.Stdout
Output io.Writer

// DisableColors defines if the logs output should be colorized
//
// Default: false
DisableColors bool

enableColors bool
enableLatency bool
timeZoneLocation *time.Location
Expand Down Expand Up @@ -87,18 +91,7 @@ var ConfigDefault = Config{
TimeZone: "Local",
TimeInterval: 500 * time.Millisecond,
Output: os.Stdout,
enableColors: true,
}

// Function to check if the logger format is compatible for coloring
func checkColorEnable(format string) bool {
validTemplates := []string{"${status}", "${method}"}
for _, template := range validTemplates {
if strings.Contains(format, template) {
return true
}
}
return false
enableColors: false,
}

// Helper function to set default values
Expand All @@ -121,7 +114,6 @@ func configDefault(config ...Config) Config {
if cfg.Format == "" {
cfg.Format = ConfigDefault.Format
}

if cfg.TimeZone == "" {
cfg.TimeZone = ConfigDefault.TimeZone
}
Expand All @@ -135,8 +127,7 @@ func configDefault(config ...Config) Config {
cfg.Output = ConfigDefault.Output
}

// Enable colors if no custom format or output is given
if cfg.Output == ConfigDefault.Output && checkColorEnable(cfg.Format) {
if !cfg.DisableColors && cfg.Output == ConfigDefault.Output {
cfg.enableColors = true
}

Expand Down
48 changes: 32 additions & 16 deletions middleware/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func New(config ...Config) fiber.Handler {
cfg.Output = colorable.NewNonColorable(os.Stdout)
}
}

errPadding := 15
errPaddingStr := strconv.Itoa(errPadding)

Expand Down Expand Up @@ -137,26 +138,41 @@ func New(config ...Config) fiber.Handler {
buf := bytebufferpool.Get()

// Default output when no custom Format or io.Writer is given
if cfg.enableColors && cfg.Format == ConfigDefault.Format {
if cfg.Format == ConfigDefault.Format {
// Format error if exist
formatErr := ""
if chainErr != nil {
formatErr = colors.Red + " | " + chainErr.Error() + colors.Reset
if cfg.enableColors {
if chainErr != nil {
formatErr = colors.Red + " | " + chainErr.Error() + colors.Reset
}
_, _ = buf.WriteString( //nolint:errcheck // This will never fail
fmt.Sprintf("%s |%s %3d %s| %7v | %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).Round(time.Millisecond),
c.IP(),
methodColor(c.Method(), colors), c.Method(), colors.Reset,
c.Path(),
formatErr,
),
)
} else {
if chainErr != nil {
formatErr = " | " + chainErr.Error()
}
_, _ = buf.WriteString( //nolint:errcheck // This will never fail
fmt.Sprintf("%s | %3d | %7v | %15s | %-7s | %-"+errPaddingStr+"s %s\n",
timestamp.Load().(string),
c.Response().StatusCode(),
data.Stop.Sub(data.Start).Round(time.Millisecond),
c.IP(),
c.Method(),
c.Path(),
formatErr,
),
)
}

// Format log to buffer
_, _ = buf.WriteString( //nolint:errcheck // This will never fail
fmt.Sprintf("%s |%s %3d %s| %7v | %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).Round(time.Millisecond),
c.IP(),
methodColor(c.Method(), colors), c.Method(), colors.Reset,
c.Path(),
formatErr,
),
)

// Write buffer to output
_, _ = cfg.Output.Write(buf.Bytes()) //nolint:errcheck // This will never fail

Expand Down
35 changes: 34 additions & 1 deletion middleware/logger/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,23 @@ func (o *fakeOutput) Write([]byte) (int, error) {
return 0, errors.New("fake output")
}

// go test -run Test_Logger_ErrorOutput_WithoutColor
func Test_Logger_ErrorOutput_WithoutColor(t *testing.T) {
t.Parallel()
o := new(fakeOutput)
app := fiber.New()
app.Use(New(Config{
Output: o,
DisableColors: true,
}))

resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)

utils.AssertEqual(t, 1, int(*o))
}

// go test -run Test_Logger_ErrorOutput
func Test_Logger_ErrorOutput(t *testing.T) {
t.Parallel()
Expand All @@ -162,7 +179,7 @@ func Test_Logger_ErrorOutput(t *testing.T) {
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)

utils.AssertEqual(t, 2, int(*o))
utils.AssertEqual(t, 1, int(*o))
}

// go test -run Test_Logger_All
Expand Down Expand Up @@ -502,3 +519,19 @@ func Test_Logger_ByteSent_Streaming(t *testing.T) {
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
utils.AssertEqual(t, "0 0 200", buf.String())
}

// go test -run Test_Logger_EnableColors
func Test_Logger_EnableColors(t *testing.T) {
t.Parallel()
o := new(fakeOutput)
app := fiber.New()
app.Use(New(Config{
Output: o,
}))

resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)

utils.AssertEqual(t, 1, int(*o))
}

0 comments on commit 06ef450

Please sign in to comment.