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

Feature Request: Add a Pre-Write Callback to Logger Middleware #3300

Open
bantawa04 opened this issue Feb 6, 2025 · 5 comments
Open

Feature Request: Add a Pre-Write Callback to Logger Middleware #3300

bantawa04 opened this issue Feb 6, 2025 · 5 comments

Comments

@bantawa04
Copy link

Currently, the logger.New middleware in Fiber writes logs to the specified Output file automatically. While the Done callback allows for post-processing of the log string, there's no way to control whether a log entry is written to the file at all before it's written. This makes it difficult to implement fine-grained logging logic, such as selectively logging certain responses based on their content or other criteria.

Problem:

I have a use case where I want to log only specific errors (e.g., 4xx/5xx status codes) to an error log file, and potentially other requests (e.g., 2xx) to a separate debug or access log file. The current Done callback is called after the log has already been written to the Output file. This results in either:

  1. Double Logging: If I use Done to filter logs and write to my error log file, the middleware also writes all logs to the Output file, leading to duplication.
  2. Inability to Selectively Log: If I don't use Done, I can't filter which log entries are written to which file.

Code from my use case

app.Use(logger.New())
app.Use(logger.New(logger.Config{
	TimeFormat: "2006-01-02 15:04:05",
	TimeZone:   "Local",
	Format:     "\n" + `{"timestamp":"${time}", "status":${status}, "latency":"${latency}", "method":"${method}", "path":"${path}", "error":"${error}", "response":[${resBody}]}`,
	Output:     errorLogFile,
	Done: func(c *fiber.Ctx, logString []byte) {
		if c.Response().StatusCode() >= 400 {
			fmt.Println("printing to error.log")
			errorLogFile.Write(logString)
			defer errorLogFile.Close()
		}
	},
}))

Proposed Solution/Feature request:

I propose adding a new callback function to the logger.Config called something like BeforeWrite or ShouldLog. This callback would be executed before the middleware writes the log entry to the Output file. The callback would receive the fiber.Ctx and the log string as arguments and would return a boolean value: true if the log should be written, and false if it should be skipped.

Example Usage:

app.Use(logger.New(logger.Config{
    TimeFormat: "2006-01-02 15:04:05",
    TimeZone:   "Local",
    Format:     `{"timestamp":"${time}", "status":${status}, ...}`, //Log format
    Output:     logFile, // General log file (optional)
    BeforeWrite: func(c *fiber.Ctx, logString []byte) bool {
        if c.Response().StatusCode() >= 400 {
            // Log errors to the error log file
            errorLogFile.Write(logString) // Example, we can write to different files here.
            return true // Write to the main log file as well (optional). We can return false if we only want to write to the error log.
        } else if c.Response().StatusCode() == 200 {
            // Log 200 OK requests to a separate access log
            accessLogFile.Write(logString)
            return true // Write to the main log file as well (optional). We can return false if we only want to write to the access log.
        }
        return false // Don't write other requests to the main log file.
    },
    Done: func(c *fiber.Ctx, logString []byte) {
        // Any post-processing 
    },
}))
Copy link

welcome bot commented Feb 6, 2025

Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@gaby
Copy link
Member

gaby commented Feb 6, 2025

I agree on adding this, got to check other logging framework to see how they name this kind of feature.

@liaohongxing
Copy link
Contributor

I agree with adding this, but BeforeWrite should be renamed, according to other middlewares in gofiber, similar names are "Next" or "Filter"

@gaby
Copy link
Member

gaby commented Feb 7, 2025

Agree with @liaohongxing this should be named Filter.

@gaby gaby added this to v3 Feb 7, 2025
@gaby gaby moved this to Todo in v3 Feb 7, 2025
@KernelDeimos
Copy link

If I can throw my own two cents in here, this feels like a job for the decorator pattern

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests

5 participants