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(logger): Add predefined log formats #3359

Merged
merged 16 commits into from
Mar 21, 2025

Conversation

edvardsanta
Copy link
Contributor

@edvardsanta edvardsanta commented Mar 18, 2025

Description

This PR introduces support for multiple logging formats in the logger middleware. Users can now specify the format as:

  • "common" β†’ Common Log Format (CLF) (Apache-style).
  • "combined" β†’ Combined CLF (includes referrer and user-agent, used in Apache & Nginx).
  • "json" β†’ JSON-structured logs.
app.Use(logger.New(logger.Config{Format: logger.FormatCommonLog}))
// or using string format
app.Use(logger.New(logger.Config{Format: "common"}))

Observation: I called them just the common and combined log formats because, in the official documentation for Apacheand Nginx, they use this formats respectively. Both web servers support extensions and customizations to these formats, but I have avoided naming them explicitly as "Nginx" and "Apache" formats since that would be redundant. For reference

Fixes #3345

Changes introduced

List the new features or adjustments introduced in this pull request. Provide details on benchmarks, documentation updates, changelog entries, and if applicable, the migration guide.

  • Benchmarks: Describe any performance benchmarks and improvements related to the changes.
  • Documentation Update: Detail the updates made to the documentation and links to the changed files.
  • Changelog/What's New: Include a summary of the additions for the upcoming release notes.
  • Migration Guide: If necessary, provide a guide or steps for users to migrate their existing code to accommodate these changes.
  • API Alignment with Express: Explain how the changes align with the Express API.
  • API Longevity: Discuss the steps taken to ensure that the new or updated APIs are consistent and not prone to breaking changes.
  • Examples: Provide examples demonstrating the new features or changes in action.

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • Enhancement (improvement to existing features and functionality)
  • Documentation update (changes to documentation)

Checklist

Before you submit your pull request, please make sure you meet these requirements:

  • Followed the inspiration of the Express.js framework for new functionalities, making them similar in usage.
  • Conducted a self-review of the code and provided comments for complex or critical parts.
  • Updated the documentation in the /docs/ directory for Fiber's documentation.
  • Added or updated unit tests to validate the effectiveness of the changes or new features.
  • Ensured that new and existing unit tests pass locally with the changes.
  • Verified that any new dependencies are essential and have been agreed upon by the maintainers/community.
  • [] Aimed for optimal performance with minimal allocations in the new code.
  • Provided benchmarks for the new code to analyze and improve upon.

Commit formatting

Please use emojis in commit messages for an easy way to identify the purpose or intention of a commit. Check out the emoji cheatsheet here: CONTRIBUTING.md

This commit introduces predefined log formats for the logger middleware, enhancing its flexibility and ease of use. Users can now specify formats like "common", "combined", and "json" in addition to the default format.

Changes:

- Added a `format.go` file to store predefined log format constants.
- Updated `config.go` to include documentation for the `Format` configuration option, explaining the available placeholders and predefined formats.
- Modified `logger.go` to utilize the predefined formats based on the `Format` configuration.
- Added a new test case `Test_Logger_CLF` in `logger_test.go` to verify the "common" log format.
Copy link

welcome bot commented Mar 18, 2025

Thanks for opening this pull request! πŸŽ‰ Please check out our contributing guidelines. If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

Copy link
Contributor

coderabbitai bot commented Mar 18, 2025

Walkthrough

This pull request introduces predefined logging formats for the Fiber logger middleware. It enhances the logger configuration by adding new fields (CustomFormat, BeforeHandlerFunc, and enableColors) and replaces the old default format with a constant (DefaultFormat). A new file defines constants for various log formats (default, common, combined, JSON, and ECS), and the documentation is updated to describe these changes with a new "Predefined Formats" section and revised usage examples. Additional tests are included to verify the new logging behaviors.

Changes

File(s) Change Summary
docs/middleware/logger.md, docs/whats_new.md Updated documentation to include a new "Predefined Formats" section, revised configuration details, and example usages; removed the filesystem middleware section.
middleware/logger/config.go, middleware/logger/default_logger.go, middleware/logger/logger.go Updated logger configuration and control flow by replacing defaultFormat with DefaultFormat, updating comments, and adding a conditional block for dynamic format lookup.
middleware/logger/format.go New file defining constants for log formats (DefaultFormat, CommonFormat, CombinedFormat, JSONFormat, and ECSFormat) to facilitate different logging requirements.
middleware/logger/logger_test.go Added tests for CLF, Combined, JSON, and ECS logging formats to verify correct log output formatting after requests.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant LoggerMiddleware
    participant FormatMap

    Client->>LoggerMiddleware: Send HTTP Request
    LoggerMiddleware->>FormatMap: Lookup cfg.Format
    alt Format exists in LoggerConfig
        FormatMap-->>LoggerMiddleware: Return corresponding format string
        LoggerMiddleware->>LoggerMiddleware: Update log format dynamically
    else
        LoggerMiddleware->>LoggerMiddleware: Use default format (DefaultFormat)
    end
    LoggerMiddleware->>Client: Process request and output log
Loading

Poem

I'm a bouncy rabbit, hopping through each line,
Logging formats now shine so fine.
From "common" to JSON, a parade in the night,
My whiskers twitch with pure delight.
With carrots and tests, I celebrate this featβ€”
A code garden where every log is sweet! πŸ₯•πŸ‡


πŸ“œ 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 1743c68 and 42cac20.

πŸ“’ Files selected for processing (3)
  • docs/middleware/logger.md (3 hunks)
  • docs/whats_new.md (1 hunks)
  • middleware/logger/config.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/whats_new.md
  • docs/middleware/logger.md

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.

This commit updates the logger middleware to utilize the predefined log formats introduced in a previous commit. It also fixes the default format to use the `FormatDefault` constant.

Changes:

-   Updated `config.go` to use `FormatDefault` constant for the default format.
-   Updated `default_logger.go` to use `FormatDefault` constant for the default format.
-   Added new test cases in `logger_test.go` to verify the "common", "combined" and "json" log formats.
-   Updated `format.go` to add newline character to the end of the default format.
@edvardsanta edvardsanta changed the title feat(logger): Add predefined log formats πŸ”₯ feat(logger): Add predefined log formats Mar 18, 2025
@edvardsanta edvardsanta marked this pull request as ready for review March 18, 2025 21:37
@edvardsanta edvardsanta requested a review from a team as a code owner March 18, 2025 21:37
@edvardsanta edvardsanta requested review from gaby, sixcolors, ReneWerner87 and efectn and removed request for a team March 18, 2025 21:37
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/middleware/logger.md (2)

171-182: Fix tab characters in markdown

The default config example uses tabs instead of spaces which is flagged by the markdown linter.

-	Next:              nil,
-	Skip:              nil,
-	Done:              nil,
-	Format:            FormatDefault,
-	TimeFormat:        "15:04:05",
-	TimeZone:          "Local",
-	TimeInterval:      500 * time.Millisecond,
-	Stream:            os.Stdout,
-	BeforeHandlerFunc: beforeHandlerFunc,
-	LoggerFunc:        defaultLoggerInstance,
-	enableColors:      true,
+    Next:              nil,
+    Skip:              nil,
+    Done:              nil,
+    Format:            FormatDefault,
+    TimeFormat:        "15:04:05",
+    TimeZone:          "Local",
+    TimeInterval:      500 * time.Millisecond,
+    Stream:            os.Stdout,
+    BeforeHandlerFunc: beforeHandlerFunc,
+    LoggerFunc:        defaultLoggerInstance,
+    enableColors:      true,
🧰 Tools
πŸͺ› markdownlint-cli2 (0.17.2)

171-171: Hard tabs
Column: 1

(MD010, no-hard-tabs)


172-172: Hard tabs
Column: 1

(MD010, no-hard-tabs)


173-173: Hard tabs
Column: 1

(MD010, no-hard-tabs)


174-174: Hard tabs
Column: 1

(MD010, no-hard-tabs)


175-175: Hard tabs
Column: 1

(MD010, no-hard-tabs)


176-176: Hard tabs
Column: 1

(MD010, no-hard-tabs)


177-177: Hard tabs
Column: 1

(MD010, no-hard-tabs)


178-178: Hard tabs
Column: 1

(MD010, no-hard-tabs)


179-179: Hard tabs
Column: 1

(MD010, no-hard-tabs)


180-180: Hard tabs
Column: 1

(MD010, no-hard-tabs)


181-181: Hard tabs
Column: 1

(MD010, no-hard-tabs)


185-192: Great addition of predefined formats section

The predefined formats table provides excellent documentation for the new feature, clearly showing the formats and their purposes.

Fix the table formatting issues:

  • Add a blank line before the table (line 187)
  • Add a trailing pipe to line 192 to match the table style
 ## Predefined Formats
 Logger provides predefined formats that you can use by name or directly by specifying the format string.
+
 | **Format Name**   | **Format Constant** | **Format String**                                                                                                  | **Description**                                                                                     |
 |-------------------|---------------------|--------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|
 | default           | `FormatDefault`      | `"[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n"`                                             | Fiber's default logger format.                                                                       |
 | common            | `FormatCommonLog`    | `"${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent}\n"`                                     | Common Log Format (CLF) used in web server logs.                                                    |
 | combined          | `FormatCombined`     | `"${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent} "${referer}" "${ua}"\n"`                 | CLF format plus the `referer` and `user agent` fields.                                               |
-| json              | `FormatJSON`         | `"{time: ${time}, ip: ${ip}, method: ${method}, url: ${url}, status: ${status}, bytesSent: ${bytesSent}}\n"`        | JSON format for structured logging.                                                             
+| json              | `FormatJSON`         | `"{time: ${time}, ip: ${ip}, method: ${method}, url: ${url}, status: ${status}, bytesSent: ${bytesSent}}\n"`        | JSON format for structured logging.                                                                 |
🧰 Tools
πŸͺ› markdownlint-cli2 (0.17.2)

187-187: Tables should be surrounded by blank lines
null

(MD058, blanks-around-tables)


192-192: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)

πŸ“œ Review details

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

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 395c8fa and a67fc2a.

πŸ“’ Files selected for processing (7)
  • docs/middleware/logger.md (3 hunks)
  • docs/whats_new.md (1 hunks)
  • middleware/logger/config.go (2 hunks)
  • middleware/logger/default_logger.go (1 hunks)
  • middleware/logger/format.go (1 hunks)
  • middleware/logger/logger.go (1 hunks)
  • middleware/logger/logger_test.go (1 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
middleware/logger/default_logger.go (1)
middleware/logger/format.go (1) (1)
  • FormatDefault (5-5)
middleware/logger/logger.go (1)
middleware/logger/format.go (1) (1)
  • LoggerConfig (17-22)
middleware/logger/config.go (1)
middleware/logger/format.go (1) (1)
  • FormatDefault (5-5)
middleware/logger/logger_test.go (2)
middleware/logger/config.go (1) (1)
  • Config (12-91)
middleware/logger/format.go (3) (3)
  • FormatCommonLog (7-7)
  • FormatCombined (9-9)
  • FormatJSON (11-11)
πŸͺ› markdownlint-cli2 (0.17.2)
docs/middleware/logger.md

171-171: Hard tabs
Column: 1

(MD010, no-hard-tabs)


172-172: Hard tabs
Column: 1

(MD010, no-hard-tabs)


173-173: Hard tabs
Column: 1

(MD010, no-hard-tabs)


174-174: Hard tabs
Column: 1

(MD010, no-hard-tabs)


175-175: Hard tabs
Column: 1

(MD010, no-hard-tabs)


176-176: Hard tabs
Column: 1

(MD010, no-hard-tabs)


177-177: Hard tabs
Column: 1

(MD010, no-hard-tabs)


178-178: Hard tabs
Column: 1

(MD010, no-hard-tabs)


179-179: Hard tabs
Column: 1

(MD010, no-hard-tabs)


180-180: Hard tabs
Column: 1

(MD010, no-hard-tabs)


181-181: Hard tabs
Column: 1

(MD010, no-hard-tabs)


187-187: Tables should be surrounded by blank lines
null

(MD058, blanks-around-tables)


192-192: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)

πŸ”‡ Additional comments (15)
middleware/logger/default_logger.go (1)

31-31: Clean refactoring to use the new format constant.

The change updates the conditional check to use FormatDefault constant instead of what was likely a variable called defaultFormat. This aligns with the new predefined formats implementation and improves code maintainability by using named constants.

middleware/logger/format.go (2)

3-12: Well-structured predefined log format constants.

These constants clearly define the various logging formats:

  1. FormatDefault - Fiber's default log format
  2. FormatCommonLog - Apache-style common log format
  3. FormatCombined - Combined log format with referrer and user-agent
  4. FormatJSON - JSON structured logging format

Each format is properly documented with a descriptive comment. The implementation aligns with the PR objectives to introduce multiple standardized logging formats.


14-22: Good implementation of the format mapping.

The LoggerConfig map provides a clean way to map string identifiers to the format constants. This allows users to configure the logger using simple string names like "common" or "json" instead of having to specify the full format string.

This approach aligns with the PR objectives and enhances usability.

middleware/logger/logger.go (1)

34-36: Excellent addition for dynamic format resolution.

This conditional block checks if the configured format string matches a key in the LoggerConfig map and updates it to the corresponding format if found. This allows users to specify formats by name (e.g., "common", "combined", "json") rather than using the full format string.

The placement is correct - after the timestamp is initialized and before the routine that updates it every 500ms.

docs/whats_new.md (1)

940-961: Great documentation for the new predefined formats feature.

This section clearly explains the predefined formats feature and provides concise examples showing how to use them. The examples demonstrate both string-based format specification ("common") and constant-based specification (logger.FormatCombined).

The documentation is well-structured and aligns perfectly with the implementation, making it easy for users to understand and use this new feature.

middleware/logger/config.go (2)

53-66: Well-documented format options!

The expanded documentation for the Format field is comprehensive and informative, providing clear examples of both custom formats and predefined options. This will make it easier for users to configure logging according to their needs.


119-119: Good refactoring to use the constant

Replacing the hardcoded default format string with the FormatDefault constant improves maintainability and ensures consistency across the codebase.

docs/middleware/logger.md (2)

92-104: Great examples for the new predefined formats

The added examples clearly demonstrate how to use each of the predefined formats, showing both string-based configuration and constant-based configuration options.


159-159: Updated documentation reflects new features

The Format field description now correctly describes the support for predefined formats, which aligns with the implementation changes.

middleware/logger/logger_test.go (6)

470-493: Good test for Common Log Format with name

This test effectively verifies that the logger middleware correctly formats output when using the "common" format string. The test validates both the configuration and the expected output format.


495-518: Good test for Common Log Format with constant

This test complements the previous one by verifying functionality when using the FormatCommonLog constant instead of the string name.


520-549: Good test for Combined Log Format with name

This test effectively verifies that the logger middleware correctly handles the "combined" format, including additional fields like referrer and user agent.


551-580: Good test for Combined Log Format with constant

This test complements the previous one by verifying functionality when using the FormatCombined constant instead of the string name.


582-610: Good test for JSON Format with name

This test effectively verifies that the logger middleware correctly formats output as JSON when using the "json" format string.


612-640: Good test for JSON Format with constant

This test complements the previous one by verifying functionality when using the FormatJSON constant instead of the string name.

@gaby gaby added the v3 label Mar 19, 2025
@gaby gaby added this to the v3 milestone Mar 19, 2025
Copy link

codecov bot commented Mar 19, 2025

Codecov Report

All modified and coverable lines are covered by tests βœ…

Project coverage is 83.74%. Comparing base (f6ac929) to head (42cac20).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3359   +/-   ##
=======================================
  Coverage   83.73%   83.74%           
=======================================
  Files         118      118           
  Lines       11728    11728           
=======================================
+ Hits         9821     9822    +1     
+ Misses       1481     1480    -1     
  Partials      426      426           
Flag Coverage Ξ”
unittests 83.74% <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.

@ReneWerner87
Copy link
Member

can we also provide the ECS format
https://www.elastic.co/guide/en/ecs-logging/overview/current/intro.html
as it is used very often

@gaby
Copy link
Member

gaby commented Mar 19, 2025

can we also provide the ECS format https://www.elastic.co/guide/en/ecs-logging/overview/current/intro.html as it is used very often

Potential implementation:

const 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"

@ReneWerner87
Copy link
Member

do you think we should add this or not, because it is too specific ?

@gaby
Copy link
Member

gaby commented Mar 19, 2025

do you think we should add this or not, because it is too specific ?

We should add it while we are at it. This will make parsing Fiber logs easier

@ReneWerner87
Copy link
Member

@edvardsanta can you do this and also check the review hints
then we are able to merge

@edvardsanta
Copy link
Contributor Author

@edvardsanta can you do this and also check the review hints then we are able to merge

Sure, I'll open a PR solving the issues and adding ECS log format.

@ReneWerner87
Copy link
Member

@edvardsanta can you do this and also check the review hints then we are able to merge

Sure, I'll open a PR solving the issues and adding ECS log format.

you can simply extend the current one, a new PR is not necessary

@edvardsanta
Copy link
Contributor Author

@edvardsanta can you do this and also check the review hints then we are able to merge

Sure, I'll open a PR solving the issues and adding ECS log format.

you can simply extend the current one, a new PR is not necessary

Sorry, not a new PR my brain isn’t working very well this morning hahaha πŸ˜†

edvardsanta and others added 4 commits March 20, 2025 23:36
This commit introduces a `CustomFormat` option to the `Config` struct, allowing users to specify a predefined format (like "common", "combined", "json", or "ecs")
-   Removed `CustomFormat` field from `Config`.
-   Removed `LoggerConfig` map.
-   Rename predefined formats constants.
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

@ReneWerner87 ReneWerner87 merged commit e947e03 into gofiber:main Mar 21, 2025
29 of 36 checks passed
Copy link

welcome bot commented Mar 21, 2025

Congrats on merging your first pull request! πŸŽ‰ We here at Fiber are proud of you! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

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.

πŸ“ [Proposal]: Add support for standard log formats
5 participants