Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔥 feat: Add Skip function to logger middleware #3333

Merged
merged 27 commits into from
Mar 10, 2025

Conversation

JIeJaitt
Copy link
Contributor

@JIeJaitt JIeJaitt commented Feb 27, 2025

Description

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.

Fixes #3300

Copy link
Contributor

coderabbitai bot commented Feb 27, 2025

Walkthrough

The pull request modifies the logger middleware configuration in the Fiber framework by renaming the Output property to Stream and introducing a new Skip property that determines if logging should be skipped based on a condition. The default configuration is updated accordingly. The changes also include updates to the documentation, tests, and the logger's control flow to accommodate these modifications.

Changes

File(s) Change Summary
docs/middleware/logger.md
middleware/logger/config.go
Renamed Output to Stream, added Skip property, and updated default configuration and related documentation.
middleware/logger/default_logger.go Introduced a conditional check for cfg.Skip in the logging process to skip logging if the condition is met, and updated output references to Stream.
middleware/logger/logger_test.go Added Test_Logger_Filter with subtests to validate logging behavior based on HTTP response statuses; updated references from Output to Stream.
docs/whats_new.md Added a new section describing the Skip function with examples demonstrating its usage in the logging middleware.

Poem

In the meadow of code where logs do play,
A rabbit hops forth to brighten the day.
With Stream in the mix and Skip by my side,
I’ll log only the tales that I take in stride.
Hooray for the changes that help us convey!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Free

📥 Commits

Reviewing files that changed from the base of the PR and between b479e96 and 903c2ac.

📒 Files selected for processing (1)
  • middleware/logger/default_logger.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • middleware/logger/default_logger.go

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Feb 27, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.67%. Comparing base (600ebd9) to head (903c2ac).
Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3333   +/-   ##
=======================================
  Coverage   83.66%   83.67%           
=======================================
  Files         118      118           
  Lines       11711    11718    +7     
=======================================
+ Hits         9798     9805    +7     
  Misses       1485     1485           
  Partials      428      428           
Flag Coverage Δ
unittests 83.67% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JIeJaitt
Copy link
Contributor Author

JIeJaitt commented Feb 27, 2025

@ReneWerner87 hi, there
Strange, this unit test runs locally for me without any problem, but reports an error in GitHub Action

@ReneWerner87
Copy link
Member

@ReneWerner87 hi, there Strange, this unit test runs locally for me without any problem, but reports an error in GitHub Action

did you also run this local with the “-race” flag ?

@gaby
Copy link
Member

gaby commented Feb 27, 2025

@ReneWerner87 hi, there Strange, this unit test runs locally for me without any problem, but reports an error in GitHub Action

did you also run this local with the “-race” flag ?

I just ran them locally with make test and it doesn't fail.

@gaby
Copy link
Member

gaby commented Feb 27, 2025

@ReneWerner87 hi, there Strange, this unit test runs locally for me without any problem, but reports an error in GitHub Action

did you also run this local with the “-race” flag ?

I just ran them locally with make test and it doesn't fail.

Using make longtest does trigger the same race condition we are seeing in the CI

@gaby
Copy link
Member

gaby commented Feb 27, 2025

@ReneWerner87 hi, there Strange, this unit test runs locally for me without any problem, but reports an error in GitHub Action

did you also run this local with the “-race” flag ?

I just ran them locally with make test and it doesn't fail.

Using make longtest does trigger the same race condition we are seeing in the CI

Pretty sure this is related to re-using the same app across all the new tests introduced in this PR. They are both running in parallel and registering /.

@gaby
Copy link
Member

gaby commented Feb 27, 2025

ok, unit-tests are passing now.

@gaby gaby marked this pull request as ready for review February 27, 2025 13:24
@gaby gaby requested a review from a team as a code owner February 27, 2025 13:24
@gaby gaby requested review from gaby, sixcolors, ReneWerner87 and efectn and removed request for a team February 27, 2025 13:24
@gaby gaby added this to the v3 milestone Feb 27, 2025
@gaby
Copy link
Member

gaby commented Mar 3, 2025

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Mar 3, 2025

✅ Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
docs/whats_new.md (1)

943-961: ⚠️ Potential issue

Critical issue: Inconsistent filter example logic.

The documentation states that when the Filter function returns true the log will be written, and when it returns false the log will be skipped. In the provided examples, the second example (logging only for status 200) is consistent with this behavior. However, in the first example the comment indicates that logging should be skipped for 404 requests, but the code returns:

return c.Response().StatusCode() == fiber.StatusNotFound

This condition returns true when the status code is 404, meaning a 404 response would be logged rather than skipped. To align the logic with the intended behavior (i.e., skip logging for 404 responses), consider inverting the condition. For example:

-        return c.Response().StatusCode() == fiber.StatusNotFound
+        return c.Response().StatusCode() != fiber.StatusNotFound

This change would ensure that the log is written only when the status code is not 404, thereby skipping 404 responses as the comment suggests.

🧹 Nitpick comments (1)
docs/middleware/logger.md (1)

142-142: New Filter Property Documentation Addition
The configuration table now includes the Filter property with the function signature func(fiber.Ctx) bool and a clear description. This documentation clearly explains that the function is invoked before writing the log output and will skip logging if it returns false. Consider adding a brief usage example in the "Examples" section to illustrate how to leverage this filter in a real scenario.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e6f4fd and 75976af.

📒 Files selected for processing (5)
  • docs/middleware/logger.md (2 hunks)
  • docs/whats_new.md (1 hunks)
  • middleware/logger/config.go (3 hunks)
  • middleware/logger/default_logger.go (1 hunks)
  • middleware/logger/logger_test.go (1 hunks)
🔇 Additional comments (7)
middleware/logger/default_logger.go (1)

18-21: Filter implementation looks correct.

This implementation adds a filter capability to the logger, allowing conditional logging based on request context. The placement at the beginning of the function is efficient as it avoids unnecessary processing for requests that should be skipped.

middleware/logger/logger_test.go (1)

174-224: Test structure looks good and effectively validates the filter functionality.

The test implementation properly verifies the filter functionality with two distinct test cases:

  1. Verifying that logs are written for 404 status codes when filtered to only log those
  2. Verifying that logs are not written for 200 status codes with the same filter

The tests correctly use a single middleware instance with both the filter and output capture, which accurately tests the filter's behavior.

middleware/logger/config.go (4)

23-27: Well-defined and properly documented feature addition.

The new Filter function field is well-designed and appropriately documented. It provides a clean extension point for conditionally logging requests based on custom logic, which addresses issue #3300 as mentioned in the PR objectives.


107-107: Appropriate default value for the new Filter field.

Setting the default value to nil is appropriate as it:

  1. Maintains backward compatibility
  2. Makes the feature optional
  3. Follows the pattern of other optional function fields in the Config struct

136-138: Proper implementation of default value handling.

The implementation correctly follows the established pattern for handling default values in the configDefault function. This ensures consistent behavior when users don't explicitly provide a filter function.


23-27:

✅ Verification successful

Verify usage examples are provided in documentation.

The implementation looks good, but users might benefit from usage examples in the documentation showing how to implement filter functions for common scenarios (e.g., filtering by status code, path, etc.).


🏁 Script executed:

#!/bin/bash
# Check if examples are provided in the logger middleware documentation

# Look for Filter examples in docs
echo "Checking for Filter usage examples in documentation..."
grep -A 10 "Filter" docs/middleware/logger.md || echo "No Filter examples found in logger documentation"

# Check if the new feature is mentioned in what's new document
echo "Checking for mention in what's new document..."
grep -A 5 "Filter" docs/whats_new.md || echo "No mention of Filter in what's new document"

Length of output: 3951


Documentation Examples Verified

The Filter usage examples are clearly present in both docs/middleware/logger.md and docs/whats_new.md, demonstrating common scenarios like filtering based on status codes. No further action is required.

docs/middleware/logger.md (1)

161-161: Default Config Update: 'Filter' Initialization
The default configuration now initializes the Filter property to nil, which preserves the existing logging behavior when no filter is provided. This is consistent with the documented default in the configuration table.

Copy link
Member

@gaby gaby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last thing

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
docs/whats_new.md (1)

921-925: Fix inconsistency between comment and code.

The comment states "log status code >= 400" but the code actually checks for status codes >= 404 (StatusNotFound). For accurate documentation, you should either update the comment or modify the condition.

- // log status code >= 400
+ // log status code >= 404
  return c.Response().StatusCode() >= fiber.StatusNotFound

Alternatively, to match the comment:

  // log status code >= 400
- return c.Response().StatusCode() >= fiber.StatusNotFound
+ return c.Response().StatusCode() >= fiber.StatusBadRequest
middleware/logger/logger_test.go (1)

174-176: Test function documentation could be improved.

Consider adding a documentation comment to explain the purpose of this test function.

+// 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()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 288edb2 and e2295e5.

📒 Files selected for processing (3)
  • docs/middleware/logger.md (2 hunks)
  • docs/whats_new.md (1 hunks)
  • middleware/logger/logger_test.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: unit (1.24.x, macos-13)
  • GitHub Check: unit (1.24.x, windows-latest)
  • GitHub Check: unit (1.23.x, windows-latest)
  • GitHub Check: Compare
  • GitHub Check: repeated
🔇 Additional comments (7)
docs/whats_new.md (3)

915-916: Filter function documentation looks good.

The description clearly explains the purpose of the Filter function: it acts as a condition to determine whether a request should be logged.


935-940: Ensure this filter works as expected.

The comment and implementation align correctly. When the filter returns true (status != 200), the log will be written, which means logs will be skipped for 200 status codes.


928-932:

❓ Verification inconclusive

Inconsistent filtering logic.

This example has a potential issue with the filter logic. The comment says "log status code == 404", but the filter is returning true when the status is 404. The documentation at line 915-916 states that when the filter returns true, the log will be written. However, there seems to be confusion in past review comments about how this interacts with the defaultLogger.

Let's verify the implementation to ensure this works as expected:


🏁 Script executed:

#!/bin/bash
# Check how the Filter is used in the logger middleware implementation

# Search for places where the Filter is checked
rg -A 3 "if c\.Filter" middleware/logger/

Length of output: 43


Action Required: Verify Logger Filter Usage Consistency

The documentation snippet in docs/whats_new.md (lines 928–932) shows a logger configuration with a Filter function that returns true when the response status is equal to fiber.StatusNotFound. According to the docs (lines 915–916), returning true should trigger logging. However, our initial search for usage of c.Filter in the logger middleware (using rg -A 3 "if c\.Filter" middleware/logger/) did not produce any output.

Please manually verify the logger middleware implementation—especially within the logger.New configuration in the middleware/logger/ directory—to ensure that the Filter logic is applied as expected and interacts correctly with the default logger behavior.

middleware/logger/logger_test.go (2)

177-198: Test implementation for 404 filters looks good.

The test correctly sets up a logger middleware with a filter that only logs 404 responses, and then verifies that the output contains "404". This confirms the filter behavior works as expected.


200-225: Test implementation for 200 filter looks good.

The test correctly sets up a filter that logs everything except 200 responses, and verifies that the output does not contain "200". This confirms that the filter successfully skips logging OK responses.

docs/middleware/logger.md (2)

142-142: Filter property documentation looks good.

The description clearly explains what the Filter function does and how it affects logging behavior.


161-161: ⚠️ Potential issue

Fix syntax error in ConfigDefault.

There's a missing comma after nil in the ConfigDefault declaration, which would cause a compilation error.

- Filter         nil,
+ Filter:         nil,

Likely an incorrect or invalid review comment.

@JIeJaitt JIeJaitt requested a review from gaby March 4, 2025 05:20
@gaby
Copy link
Member

gaby commented Mar 9, 2025

@ksw2000 @efectn Can you take a look at this PR? Thanks

@gaby
Copy link
Member

gaby commented Mar 9, 2025

@JIeJaitt I updated the logic per recommendation from OpenAI o1 and added more unit tests

Copy link
Member

@gaby gaby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 LGTM

@gaby gaby changed the title 🔥 feat: Add Filter option to logger middleware 🔥 feat: Add Skip function to logger middleware Mar 10, 2025
@gaby
Copy link
Member

gaby commented Mar 10, 2025

Renamed:

  • Function Filter() -> Skip()
  • Field Output -> Stream

These now match the official expressjs middleware https://github.com/expressjs/morgan

@JIeJaitt
Copy link
Contributor Author

👍 LGTM

@ReneWerner87 ReneWerner87 merged commit c0599ee into gofiber:main Mar 10, 2025
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Feature Request: Add a Pre-Write Callback to Logger Middleware
3 participants