Building a Request Logger Middleware in Go
Middleware is a fundamental concept in Go web development, allowing you to intercept and process requests before they reach your handler function. This challenge asks you to implement a simple request logger middleware that logs incoming requests, including their method, path, and status code, to the console. This is a common and useful pattern for debugging, monitoring, and auditing web applications.
Problem Description
You need to create a Go middleware function that takes an http.Handler as input and returns a new http.Handler. The middleware should:
- Log Request Information: Before passing the request to the next handler, log the request's method, URL path, and a placeholder for the status code (which will be populated after the handler executes).
- Log Status Code: After the request has been handled by the next handler, log the status code returned by the handler.
- Pass Request to Next Handler: Ensure the request is properly passed to the next handler in the chain.
- Handle Errors: If an error occurs during the middleware's execution, log the error and continue processing the request.
The middleware should be generic and work with any http.Handler.
Examples
Example 1:
Input:
- A request to "/hello" using the GET method.
- A handler that returns a 200 status code and the text "Hello, world!".
Output (to console):
2023-10-27T10:00:00Z GET /hello
2023-10-27T10:00:00Z GET /hello - Status: 200
Example 2:
Input:
- A request to "/error" using the POST method.
- A handler that returns a 404 status code.
Output (to console):
2023-10-27T10:01:00Z POST /error
2023-10-27T10:01:00Z POST /error - Status: 404
Example 3: (Edge Case - Error in Handler)
Input:
- A request to "/panic" using the GET method.
- A handler that panics.
Output (to console):
2023-10-27T10:02:00Z GET /panic
2023-10-27T10:02:00Z GET /panic - Status: [Handler panicked - Error logged]
Constraints
- The middleware must be implemented as a function that accepts an
http.Handlerand returns anhttp.Handler. - The logging should be done to standard output (console).
- The timestamp in the log should be in ISO 8601 format (e.g.,
2023-10-27T10:00:00Z). You can use thetime.Now().Format(time.RFC3339)function for this. - The middleware should not significantly impact the performance of the application. Avoid unnecessary allocations or complex operations.
- The middleware should handle panics gracefully within the handler and log the error.
Notes
- Consider using
http.ResponseWriterto capture the status code after the handler has executed. - The
ServeHTTPmethod of the middleware handler is where the core logic resides. - Think about how to recover from panics within the handler to prevent the entire server from crashing. The
recover()function can be helpful. - This is a simplified example; real-world middleware often involves more complex logic, such as authentication, authorization, and request transformation.