From 8a74ebaa6f4f604bd73765e962c63ac620e6694a Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 16:36:46 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=F0=9F=94=A5=20Feature(logger):=20Add=20F?= =?UTF-8?q?ilter=20option=20to=20logger=20middleware?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/middleware/logger.md | 2 ++ middleware/logger/config.go | 10 ++++++++ middleware/logger/default_logger.go | 5 ++++ middleware/logger/logger_test.go | 39 +++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/docs/middleware/logger.md b/docs/middleware/logger.md index 07ff07c4de..e06d0e58fc 100644 --- a/docs/middleware/logger.md +++ b/docs/middleware/logger.md @@ -139,6 +139,7 @@ Writing to os.File is goroutine-safe, but if you are using a custom Output that | Property | Type | Description | Default | |:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| | Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | +| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output, and pass the log string as parameter. | `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}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` | @@ -157,6 +158,7 @@ Writing to os.File is goroutine-safe, but if you are using a custom Output that ```go var ConfigDefault = Config{ Next: nil, + Filter nil, Done: nil, Format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n", TimeFormat: "15:04:05", diff --git a/middleware/logger/config.go b/middleware/logger/config.go index 4826151e46..0b9d5ffaf1 100644 --- a/middleware/logger/config.go +++ b/middleware/logger/config.go @@ -20,6 +20,12 @@ type Config struct { // Optional. Default: nil Next func(c fiber.Ctx) bool + // Filter is a function that is called before writing the log string. + // If it returns true, the log will be written; otherwise, it will be skipped. + // + // Optional. Default: nil + Filter 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. // @@ -98,6 +104,7 @@ type LogFunc func(output Buffer, c fiber.Ctx, data *Data, extraParam string) (in // ConfigDefault is the default config var ConfigDefault = Config{ Next: nil, + Filter: nil, Done: nil, Format: defaultFormat, TimeFormat: "15:04:05", @@ -126,6 +133,9 @@ func configDefault(config ...Config) Config { if cfg.Next == nil { cfg.Next = ConfigDefault.Next } + if cfg.Filter == nil { + cfg.Filter = ConfigDefault.Filter + } if cfg.Done == nil { cfg.Done = ConfigDefault.Done } diff --git a/middleware/logger/default_logger.go b/middleware/logger/default_logger.go index 369b2c8580..168ce7411d 100644 --- a/middleware/logger/default_logger.go +++ b/middleware/logger/default_logger.go @@ -90,6 +90,11 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { buf.WriteString("\n") } + // Check if Filter is defined and call it + if cfg.Filter != nil && !cfg.Filter(c) { + return nil // Skip logging if Filter returns false + } + // Write buffer to output writeLog(cfg.Output, buf.Bytes()) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index d459f22c59..ccf881bc70 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -171,6 +171,45 @@ func Test_Logger_Done(t *testing.T) { require.Positive(t, buf.Len(), 0) } +func Test_Logger_Filter(t *testing.T) { + t.Parallel() + app := fiber.New() + + var logOutput bytes.Buffer // 用于捕获日志输出 + + // 创建一个日志中间件,Filter只记录404状态的日志 + app.Use(New(Config{ + Output: &logOutput, // 将日志输出重定向到logOutput + Filter: func(c fiber.Ctx) bool { + return c.Response().StatusCode() == fiber.StatusNotFound + }, + })) + + // 测试404状态码 + t.Run("Test Not Found", func(t *testing.T) { + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/nonexistent", nil)) + require.NoError(t, err) + require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + + // 验证日志输出是否包含404的日志 + require.Contains(t, logOutput.String(), "404") // 检查日志中是否包含404 + }) + + // 测试200状态码 + t.Run("Test OK", func(t *testing.T) { + app.Get("/", func(c fiber.Ctx) error { + return c.SendStatus(fiber.StatusOK) + }) + + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) + require.NoError(t, err) + require.Equal(t, fiber.StatusOK, resp.StatusCode) + + // 验证日志输出是否不包含200的日志 + require.NotContains(t, logOutput.String(), "200") // 检查日志中是否不包含200 + }) +} + // go test -run Test_Logger_ErrorTimeZone func Test_Logger_ErrorTimeZone(t *testing.T) { t.Parallel() From 0a70ee8d06849a684e75875d0038c3f2481632db Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 16:39:29 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=F0=9F=93=9A=20Doc(logger):=20Clarify=20F?= =?UTF-8?q?ilter=20middleware=20description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/middleware/logger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/middleware/logger.md b/docs/middleware/logger.md index e06d0e58fc..3fa390eaeb 100644 --- a/docs/middleware/logger.md +++ b/docs/middleware/logger.md @@ -139,7 +139,7 @@ Writing to os.File is goroutine-safe, but if you are using a custom Output that | Property | Type | Description | Default | |:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| | Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output, and pass the log string as parameter. | `nil` | +| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output. | `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}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` | From efdd738c1135397693dfd8ac328d2ddd342793e8 Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 16:48:44 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=F0=9F=9A=A8=20Test(logger):=20Enhance=20?= =?UTF-8?q?logger=20filter=20test=20with=20parallel=20subtests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middleware/logger/logger_test.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index ccf881bc70..ca26fc180e 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -175,28 +175,32 @@ func Test_Logger_Filter(t *testing.T) { t.Parallel() app := fiber.New() - var logOutput bytes.Buffer // 用于捕获日志输出 + var logOutput bytes.Buffer // Buffer to capture log output - // 创建一个日志中间件,Filter只记录404状态的日志 + // Create a logging middleware that filters logs to only include 404 status codes app.Use(New(Config{ - Output: &logOutput, // 将日志输出重定向到logOutput + Output: &logOutput, // Redirect log output to the logOutput buffer Filter: func(c fiber.Ctx) bool { return c.Response().StatusCode() == fiber.StatusNotFound }, })) - // 测试404状态码 + // Log only 404 status codes t.Run("Test Not Found", func(t *testing.T) { + t.Parallel() + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/nonexistent", nil)) require.NoError(t, err) require.Equal(t, fiber.StatusNotFound, resp.StatusCode) - // 验证日志输出是否包含404的日志 - require.Contains(t, logOutput.String(), "404") // 检查日志中是否包含404 + // Verify the log output contains the "404" message + require.Contains(t, logOutput.String(), "404") // Check if the log contains "404" }) - // 测试200状态码 + // Subtest for 200 status code t.Run("Test OK", func(t *testing.T) { + t.Parallel() + app.Get("/", func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusOK) }) @@ -205,8 +209,8 @@ func Test_Logger_Filter(t *testing.T) { require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) - // 验证日志输出是否不包含200的日志 - require.NotContains(t, logOutput.String(), "200") // 检查日志中是否不包含200 + // Verify the log output does not contain the "200" message + require.NotContains(t, logOutput.String(), "200") // Check if the log does not contain "200" }) } From a652e629feefeea449799faa1efaaf709f20717d Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 17:11:39 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=F0=9F=94=92=20Test(logger):=20Add=20mute?= =?UTF-8?q?x=20to=20prevent=20race=20conditions=20in=20logger=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middleware/logger/logger_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index ca26fc180e..a90a78806a 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -176,6 +176,7 @@ func Test_Logger_Filter(t *testing.T) { app := fiber.New() var logOutput bytes.Buffer // Buffer to capture log output + var mu sync.Mutex // Create a logging middleware that filters logs to only include 404 status codes app.Use(New(Config{ @@ -194,6 +195,8 @@ func Test_Logger_Filter(t *testing.T) { require.Equal(t, fiber.StatusNotFound, resp.StatusCode) // Verify the log output contains the "404" message + mu.Lock() + defer mu.Unlock() require.Contains(t, logOutput.String(), "404") // Check if the log contains "404" }) @@ -210,6 +213,8 @@ func Test_Logger_Filter(t *testing.T) { require.Equal(t, fiber.StatusOK, resp.StatusCode) // Verify the log output does not contain the "200" message + mu.Lock() + defer mu.Unlock() require.NotContains(t, logOutput.String(), "200") // Check if the log does not contain "200" }) } From c1f227825b6c33c3f4f80f6c59f9103e65dff15e Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 16:36:46 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=F0=9F=94=A5=20Feature(logger):=20Add=20F?= =?UTF-8?q?ilter=20option=20to=20logger=20middleware?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/middleware/logger.md | 2 ++ middleware/logger/config.go | 10 ++++++++ middleware/logger/default_logger.go | 5 ++++ middleware/logger/logger_test.go | 39 +++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/docs/middleware/logger.md b/docs/middleware/logger.md index 07ff07c4de..e06d0e58fc 100644 --- a/docs/middleware/logger.md +++ b/docs/middleware/logger.md @@ -139,6 +139,7 @@ Writing to os.File is goroutine-safe, but if you are using a custom Output that | Property | Type | Description | Default | |:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| | Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | +| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output, and pass the log string as parameter. | `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}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` | @@ -157,6 +158,7 @@ Writing to os.File is goroutine-safe, but if you are using a custom Output that ```go var ConfigDefault = Config{ Next: nil, + Filter nil, Done: nil, Format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n", TimeFormat: "15:04:05", diff --git a/middleware/logger/config.go b/middleware/logger/config.go index 4826151e46..0b9d5ffaf1 100644 --- a/middleware/logger/config.go +++ b/middleware/logger/config.go @@ -20,6 +20,12 @@ type Config struct { // Optional. Default: nil Next func(c fiber.Ctx) bool + // Filter is a function that is called before writing the log string. + // If it returns true, the log will be written; otherwise, it will be skipped. + // + // Optional. Default: nil + Filter 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. // @@ -98,6 +104,7 @@ type LogFunc func(output Buffer, c fiber.Ctx, data *Data, extraParam string) (in // ConfigDefault is the default config var ConfigDefault = Config{ Next: nil, + Filter: nil, Done: nil, Format: defaultFormat, TimeFormat: "15:04:05", @@ -126,6 +133,9 @@ func configDefault(config ...Config) Config { if cfg.Next == nil { cfg.Next = ConfigDefault.Next } + if cfg.Filter == nil { + cfg.Filter = ConfigDefault.Filter + } if cfg.Done == nil { cfg.Done = ConfigDefault.Done } diff --git a/middleware/logger/default_logger.go b/middleware/logger/default_logger.go index 369b2c8580..168ce7411d 100644 --- a/middleware/logger/default_logger.go +++ b/middleware/logger/default_logger.go @@ -90,6 +90,11 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { buf.WriteString("\n") } + // Check if Filter is defined and call it + if cfg.Filter != nil && !cfg.Filter(c) { + return nil // Skip logging if Filter returns false + } + // Write buffer to output writeLog(cfg.Output, buf.Bytes()) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index d459f22c59..ccf881bc70 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -171,6 +171,45 @@ func Test_Logger_Done(t *testing.T) { require.Positive(t, buf.Len(), 0) } +func Test_Logger_Filter(t *testing.T) { + t.Parallel() + app := fiber.New() + + var logOutput bytes.Buffer // 用于捕获日志输出 + + // 创建一个日志中间件,Filter只记录404状态的日志 + app.Use(New(Config{ + Output: &logOutput, // 将日志输出重定向到logOutput + Filter: func(c fiber.Ctx) bool { + return c.Response().StatusCode() == fiber.StatusNotFound + }, + })) + + // 测试404状态码 + t.Run("Test Not Found", func(t *testing.T) { + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/nonexistent", nil)) + require.NoError(t, err) + require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + + // 验证日志输出是否包含404的日志 + require.Contains(t, logOutput.String(), "404") // 检查日志中是否包含404 + }) + + // 测试200状态码 + t.Run("Test OK", func(t *testing.T) { + app.Get("/", func(c fiber.Ctx) error { + return c.SendStatus(fiber.StatusOK) + }) + + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) + require.NoError(t, err) + require.Equal(t, fiber.StatusOK, resp.StatusCode) + + // 验证日志输出是否不包含200的日志 + require.NotContains(t, logOutput.String(), "200") // 检查日志中是否不包含200 + }) +} + // go test -run Test_Logger_ErrorTimeZone func Test_Logger_ErrorTimeZone(t *testing.T) { t.Parallel() From 279476160aad0f50a691bab11db6f0d393079003 Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 16:39:29 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=F0=9F=93=9A=20Doc(logger):=20Clarify=20F?= =?UTF-8?q?ilter=20middleware=20description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/middleware/logger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/middleware/logger.md b/docs/middleware/logger.md index e06d0e58fc..3fa390eaeb 100644 --- a/docs/middleware/logger.md +++ b/docs/middleware/logger.md @@ -139,7 +139,7 @@ Writing to os.File is goroutine-safe, but if you are using a custom Output that | Property | Type | Description | Default | |:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| | Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output, and pass the log string as parameter. | `nil` | +| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output. | `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}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` | From 2fd940e5a1bee0db6cb731594942fac8acb08651 Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 16:48:44 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=F0=9F=9A=A8=20Test(logger):=20Enhance=20?= =?UTF-8?q?logger=20filter=20test=20with=20parallel=20subtests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middleware/logger/logger_test.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index ccf881bc70..ca26fc180e 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -175,28 +175,32 @@ func Test_Logger_Filter(t *testing.T) { t.Parallel() app := fiber.New() - var logOutput bytes.Buffer // 用于捕获日志输出 + var logOutput bytes.Buffer // Buffer to capture log output - // 创建一个日志中间件,Filter只记录404状态的日志 + // Create a logging middleware that filters logs to only include 404 status codes app.Use(New(Config{ - Output: &logOutput, // 将日志输出重定向到logOutput + Output: &logOutput, // Redirect log output to the logOutput buffer Filter: func(c fiber.Ctx) bool { return c.Response().StatusCode() == fiber.StatusNotFound }, })) - // 测试404状态码 + // Log only 404 status codes t.Run("Test Not Found", func(t *testing.T) { + t.Parallel() + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/nonexistent", nil)) require.NoError(t, err) require.Equal(t, fiber.StatusNotFound, resp.StatusCode) - // 验证日志输出是否包含404的日志 - require.Contains(t, logOutput.String(), "404") // 检查日志中是否包含404 + // Verify the log output contains the "404" message + require.Contains(t, logOutput.String(), "404") // Check if the log contains "404" }) - // 测试200状态码 + // Subtest for 200 status code t.Run("Test OK", func(t *testing.T) { + t.Parallel() + app.Get("/", func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusOK) }) @@ -205,8 +209,8 @@ func Test_Logger_Filter(t *testing.T) { require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) - // 验证日志输出是否不包含200的日志 - require.NotContains(t, logOutput.String(), "200") // 检查日志中是否不包含200 + // Verify the log output does not contain the "200" message + require.NotContains(t, logOutput.String(), "200") // Check if the log does not contain "200" }) } From 7dcc9045c9d1896cf82204621fa29939531c40c1 Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 17:11:39 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=F0=9F=94=92=20Test(logger):=20Add=20mute?= =?UTF-8?q?x=20to=20prevent=20race=20conditions=20in=20logger=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middleware/logger/logger_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index ca26fc180e..a90a78806a 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -176,6 +176,7 @@ func Test_Logger_Filter(t *testing.T) { app := fiber.New() var logOutput bytes.Buffer // Buffer to capture log output + var mu sync.Mutex // Create a logging middleware that filters logs to only include 404 status codes app.Use(New(Config{ @@ -194,6 +195,8 @@ func Test_Logger_Filter(t *testing.T) { require.Equal(t, fiber.StatusNotFound, resp.StatusCode) // Verify the log output contains the "404" message + mu.Lock() + defer mu.Unlock() require.Contains(t, logOutput.String(), "404") // Check if the log contains "404" }) @@ -210,6 +213,8 @@ func Test_Logger_Filter(t *testing.T) { require.Equal(t, fiber.StatusOK, resp.StatusCode) // Verify the log output does not contain the "200" message + mu.Lock() + defer mu.Unlock() require.NotContains(t, logOutput.String(), "200") // Check if the log does not contain "200" }) } From d6e64a0745db8d979b4d2ad7c22f37ee4d311d5f Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Thu, 27 Feb 2025 17:31:44 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=F0=9F=9A=A8=20Test(logger):=20Refactor?= =?UTF-8?q?=20logger=20test=20to=20improve=20test=20isolation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middleware/logger/logger_test.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index a90a78806a..d165c66e97 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -175,12 +175,8 @@ func Test_Logger_Filter(t *testing.T) { t.Parallel() app := fiber.New() - var logOutput bytes.Buffer // Buffer to capture log output - var mu sync.Mutex - // Create a logging middleware that filters logs to only include 404 status codes app.Use(New(Config{ - Output: &logOutput, // Redirect log output to the logOutput buffer Filter: func(c fiber.Ctx) bool { return c.Response().StatusCode() == fiber.StatusNotFound }, @@ -190,13 +186,18 @@ func Test_Logger_Filter(t *testing.T) { t.Run("Test Not Found", func(t *testing.T) { t.Parallel() + logOutput := bytes.Buffer{} + + // Redirect log output to the logOutput buffer + app.Use(New(Config{ + Output: &logOutput, + })) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/nonexistent", nil)) require.NoError(t, err) require.Equal(t, fiber.StatusNotFound, resp.StatusCode) // Verify the log output contains the "404" message - mu.Lock() - defer mu.Unlock() require.Contains(t, logOutput.String(), "404") // Check if the log contains "404" }) @@ -204,17 +205,22 @@ func Test_Logger_Filter(t *testing.T) { t.Run("Test OK", func(t *testing.T) { t.Parallel() + logOutput := bytes.Buffer{} + app.Get("/", func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusOK) }) + // Redirect log output to the logOutput buffer + app.Use(New(Config{ + Output: &logOutput, + })) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) // Verify the log output does not contain the "200" message - mu.Lock() - defer mu.Unlock() require.NotContains(t, logOutput.String(), "200") // Check if the log does not contain "200" }) } From 93b57a995231ab38a52c2c255c0a93de69d24909 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Thu, 27 Feb 2025 08:21:37 -0500 Subject: [PATCH 10/16] Fix issue with unit-tests --- middleware/logger/logger_test.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index d165c66e97..5975060a6c 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -173,18 +173,18 @@ func Test_Logger_Done(t *testing.T) { func Test_Logger_Filter(t *testing.T) { t.Parallel() - app := fiber.New() - - // Create a logging middleware that filters logs to only include 404 status codes - app.Use(New(Config{ - Filter: func(c fiber.Ctx) bool { - return c.Response().StatusCode() == fiber.StatusNotFound - }, - })) // Log only 404 status codes t.Run("Test Not Found", func(t *testing.T) { t.Parallel() + app := fiber.New() + + // Create a logging middleware that filters logs to only include 404 status codes + app.Use(New(Config{ + Filter: func(c fiber.Ctx) bool { + return c.Response().StatusCode() == fiber.StatusNotFound + }, + })) logOutput := bytes.Buffer{} @@ -204,6 +204,14 @@ func Test_Logger_Filter(t *testing.T) { // Subtest for 200 status code t.Run("Test OK", func(t *testing.T) { t.Parallel() + app := fiber.New() + + // Create a logging middleware that filters logs to only include 404 status codes + app.Use(New(Config{ + Filter: func(c fiber.Ctx) bool { + return c.Response().StatusCode() == fiber.StatusNotFound + }, + })) logOutput := bytes.Buffer{} From b60018323c4198c36475cfb8a316da1d3f9815b3 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Thu, 27 Feb 2025 09:25:36 -0500 Subject: [PATCH 11/16] Update middleware/logger/logger_test.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- middleware/logger/logger_test.go | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index 5975060a6c..58920adc6e 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -174,22 +174,17 @@ func Test_Logger_Done(t *testing.T) { func Test_Logger_Filter(t *testing.T) { t.Parallel() - // Log only 404 status codes t.Run("Test Not Found", func(t *testing.T) { t.Parallel() app := fiber.New() - // Create a logging middleware that filters logs to only include 404 status codes + logOutput := bytes.Buffer{} + + // Create a single logging middleware with both filter and output capture app.Use(New(Config{ Filter: func(c fiber.Ctx) bool { return c.Response().StatusCode() == fiber.StatusNotFound }, - })) - - logOutput := bytes.Buffer{} - - // Redirect log output to the logOutput buffer - app.Use(New(Config{ Output: &logOutput, })) @@ -198,38 +193,33 @@ func Test_Logger_Filter(t *testing.T) { require.Equal(t, fiber.StatusNotFound, resp.StatusCode) // Verify the log output contains the "404" message - require.Contains(t, logOutput.String(), "404") // Check if the log contains "404" + require.Contains(t, logOutput.String(), "404") }) - // Subtest for 200 status code t.Run("Test OK", func(t *testing.T) { t.Parallel() app := fiber.New() - // Create a logging middleware that filters logs to only include 404 status codes + logOutput := bytes.Buffer{} + + // Create a single logging middleware with both filter and output capture app.Use(New(Config{ Filter: func(c fiber.Ctx) bool { return c.Response().StatusCode() == fiber.StatusNotFound }, + Output: &logOutput, })) - logOutput := bytes.Buffer{} - app.Get("/", func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusOK) }) - // Redirect log output to the logOutput buffer - app.Use(New(Config{ - Output: &logOutput, - })) - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) // Verify the log output does not contain the "200" message - require.NotContains(t, logOutput.String(), "200") // Check if the log does not contain "200" + require.NotContains(t, logOutput.String(), "200") }) } From 2154baf7513a53ecdf7631af4c329bc1b4d6142b Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Sat, 1 Mar 2025 14:20:22 -0500 Subject: [PATCH 12/16] Apply logger filter as soon as possible --- middleware/logger/default_logger.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/middleware/logger/default_logger.go b/middleware/logger/default_logger.go index 168ce7411d..14ad6a1a1c 100644 --- a/middleware/logger/default_logger.go +++ b/middleware/logger/default_logger.go @@ -15,6 +15,11 @@ import ( // default logger for fiber func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { + // Check if Filter is defined and call it + if cfg.Filter != nil && !cfg.Filter(c) { + return nil // Skip logging if Filter returns false + } + // Alias colors colors := c.App().Config().ColorScheme @@ -90,11 +95,6 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { buf.WriteString("\n") } - // Check if Filter is defined and call it - if cfg.Filter != nil && !cfg.Filter(c) { - return nil // Skip logging if Filter returns false - } - // Write buffer to output writeLog(cfg.Output, buf.Bytes()) From 6528b9f02f30258e45efbece1dd0fa936c1fe088 Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Mon, 3 Mar 2025 09:43:02 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=F0=9F=93=9A=20Doc:=20Add=20logger=20filt?= =?UTF-8?q?er=20configuration=20example=20to=20whats=5Fnew.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/whats_new.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/whats_new.md b/docs/whats_new.md index 5c3dd6ac9a..33b5a39e6f 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -940,6 +940,26 @@ The Healthcheck middleware has been enhanced to support more than two routes, wi Refer to the [healthcheck middleware migration guide](./middleware/healthcheck.md) or the [general migration guide](#-migration-guide) to review the changes. +### Filter + +The `Filter` is a function that is called before the log string for a request is written to Output. If it returns true, the log will be written; otherwise, it will be skipped. + +```go +app.Use(logger.New(logger.Config{ + Filter: func(c fiber.Ctx) bool { + // Skip logging for 404 requests + return c.Response().StatusCode() == fiber.StatusNotFound + }, +})) + +app.Use(logger.New(logger.Config{ + Filter: func(c fiber.Ctx) bool { + // Only log requests with status code 200 + return c.Response().StatusCode() == fiber.StatusOK + }, +})) +``` + ## 🔌 Addons In v3, Fiber introduced Addons. Addons are additional useful packages that can be used in Fiber. From 288edb2611c64976c9e54eaf79de82d2caefee65 Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Mon, 3 Mar 2025 22:32:28 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=F0=9F=93=9A=20Doc:=20Update=20logger=20f?= =?UTF-8?q?ilter=20documentation=20in=20whats=5Fnew.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/whats_new.md | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/docs/whats_new.md b/docs/whats_new.md index 33b5a39e6f..6bb64c7192 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -912,6 +912,29 @@ func main() { +The `Filter` is a function that is called before the log string for a request is written to Output. If it returns true, the log will be written; otherwise, it will be skipped. + +
+Example + +```go +app.Use(logger.New(logger.Config{ + Filter: func(c fiber.Ctx) bool { + // Skip logging for 404 requests + return c.Response().StatusCode() == fiber.StatusNotFound + }, +})) + +app.Use(logger.New(logger.Config{ + Filter: func(c fiber.Ctx) bool { + // Only log requests with status code 200 + return c.Response().StatusCode() == fiber.StatusOK + }, +})) +``` + +
+ ### Filesystem We've decided to remove filesystem middleware to clear up the confusion between static and filesystem middleware. @@ -940,26 +963,6 @@ The Healthcheck middleware has been enhanced to support more than two routes, wi Refer to the [healthcheck middleware migration guide](./middleware/healthcheck.md) or the [general migration guide](#-migration-guide) to review the changes. -### Filter - -The `Filter` is a function that is called before the log string for a request is written to Output. If it returns true, the log will be written; otherwise, it will be skipped. - -```go -app.Use(logger.New(logger.Config{ - Filter: func(c fiber.Ctx) bool { - // Skip logging for 404 requests - return c.Response().StatusCode() == fiber.StatusNotFound - }, -})) - -app.Use(logger.New(logger.Config{ - Filter: func(c fiber.Ctx) bool { - // Only log requests with status code 200 - return c.Response().StatusCode() == fiber.StatusOK - }, -})) -``` - ## 🔌 Addons In v3, Fiber introduced Addons. Addons are additional useful packages that can be used in Fiber. From e2295e51073d01c84fdc9a65c0d7309ef967ecca Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Tue, 4 Mar 2025 11:07:01 +0800 Subject: [PATCH 15/16] =?UTF-8?q?=F0=9F=93=9A=20Doc:=20Update=20logger=20f?= =?UTF-8?q?ilter=20documentation=20and=20examples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/middleware/logger.md | 2 +- docs/whats_new.md | 13 ++++++++++--- middleware/logger/logger_test.go | 4 +++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/middleware/logger.md b/docs/middleware/logger.md index 3fa390eaeb..68d5955791 100644 --- a/docs/middleware/logger.md +++ b/docs/middleware/logger.md @@ -139,7 +139,7 @@ Writing to os.File is goroutine-safe, but if you are using a custom Output that | Property | Type | Description | Default | |:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| | Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output. | `nil` | +| Filter | `func(fiber.Ctx) bool` | Filter is a function that is called before the log string for a request is written to Output. If it returns true, the log will be written; otherwise, it will be skipped. | `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}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` | diff --git a/docs/whats_new.md b/docs/whats_new.md index 6bb64c7192..ecd147105c 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -920,15 +920,22 @@ The `Filter` is a function that is called before the log string for a request is ```go app.Use(logger.New(logger.Config{ Filter: func(c fiber.Ctx) bool { - // Skip logging for 404 requests + // log status code >= 400 + return c.Response().StatusCode() >= fiber.StatusNotFound + }, +})) + +app.Use(logger.New(logger.Config{ + Filter: func(c fiber.Ctx) bool { + // log status code == 404 return c.Response().StatusCode() == fiber.StatusNotFound }, })) app.Use(logger.New(logger.Config{ Filter: func(c fiber.Ctx) bool { - // Only log requests with status code 200 - return c.Response().StatusCode() == fiber.StatusOK + // log status code != 200 + return c.Response().StatusCode() != fiber.StatusOK }, })) ``` diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index 58920adc6e..36b2aef18b 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -183,6 +183,7 @@ func Test_Logger_Filter(t *testing.T) { // Create a single logging middleware with both filter and output capture app.Use(New(Config{ Filter: func(c fiber.Ctx) bool { + // log status code == 404 return c.Response().StatusCode() == fiber.StatusNotFound }, Output: &logOutput, @@ -205,7 +206,8 @@ func Test_Logger_Filter(t *testing.T) { // Create a single logging middleware with both filter and output capture app.Use(New(Config{ Filter: func(c fiber.Ctx) bool { - return c.Response().StatusCode() == fiber.StatusNotFound + // log status code != 200 + return c.Response().StatusCode() != fiber.StatusOK }, Output: &logOutput, })) From 0ac13c81bf8a1372aff1ec8b053500de47ebc9a4 Mon Sep 17 00:00:00 2001 From: JIeJaitt <498938874@qq.com> Date: Tue, 4 Mar 2025 11:17:51 +0800 Subject: [PATCH 16/16] =?UTF-8?q?=F0=9F=A9=B9=20Fix:=20improve=20what=5Fne?= =?UTF-8?q?w.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/whats_new.md | 2 +- middleware/logger/logger_test.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/whats_new.md b/docs/whats_new.md index ecd147105c..29f46b4549 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -921,7 +921,7 @@ The `Filter` is a function that is called before the log string for a request is app.Use(logger.New(logger.Config{ Filter: func(c fiber.Ctx) bool { // log status code >= 400 - return c.Response().StatusCode() >= fiber.StatusNotFound + return c.Response().StatusCode() >= fiber.StatusBadRequest }, })) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index 36b2aef18b..916f6d9e74 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -171,6 +171,8 @@ func Test_Logger_Done(t *testing.T) { require.Positive(t, buf.Len(), 0) } +// Test_Logger_Filter tests the Filter functionality of the logger middleware. +// It verifies that logs are written or skipped based on the filter condition. func Test_Logger_Filter(t *testing.T) { t.Parallel()