Hone logo
Hone
Problems

Implementing a Request Logging Middleware in Go

This challenge focuses on implementing middleware for a web server in Go. Middleware is a powerful pattern that allows you to intercept and process HTTP requests before they reach the final handler, or process responses before they are sent back to the client. A common use case is logging, which is essential for debugging, monitoring, and understanding application behavior.

Problem Description

Your task is to create a logging middleware function that wraps an existing http.Handler in Go. This middleware should log details about each incoming HTTP request before passing it to the next handler in the chain.

Key Requirements:

  1. Log Request Details: The middleware should log the following information for each request:
    • HTTP method (e.g., GET, POST)
    • Request URL (path and query parameters)
    • Remote IP address of the client
    • Timestamp of the request
  2. Pass to Next Handler: After logging, the middleware must call the ServeHTTP method of the http.Handler it's wrapping, allowing the request to proceed to the next stage in the request pipeline.
  3. Return Modified Handler: The middleware function should return a new http.Handler that incorporates the logging logic.
  4. Handle Different Request Methods: The middleware should correctly log requests regardless of their HTTP method.
  5. Clear Output Format: The logged output should be easily readable and consistent.

Expected Behavior:

When a request is made to the server, the middleware should execute, print the specified request details to the standard output (or a designated logger), and then forward the request to the original handler. The original handler will then process the request and send its response.

Edge Cases to Consider:

  • Requests with query parameters.
  • Requests originating from different IP addresses.
  • Requests that might cause an error in the underlying handler (though your middleware itself shouldn't introduce errors, it should gracefully pass requests along).

Examples

Example 1:

  • Input: A request to /users?id=123 with method GET from 192.168.1.100.
  • Output (to stdout):
    [2023-10-27 10:30:00] GET /users?id=123 from 192.168.1.100
    
    (Note: The timestamp will vary)
  • Explanation: The middleware intercepts the GET request to /users?id=123 from 192.168.1.100, logs this information with a timestamp, and then passes the request to the actual handler for /users.

Example 2:

  • Input: A POST request to /items from 10.0.0.5.
  • Output (to stdout):
    [2023-10-27 10:35:15] POST /items from 10.0.0.5
    
    (Note: The timestamp will vary)
  • Explanation: Similar to Example 1, the middleware logs the POST request details before forwarding it.

Constraints

  • The middleware function signature should adhere to the standard Go http.Handler pattern, likely taking an http.Handler as an argument and returning an http.Handler.
  • The logged output should be printed to os.Stdout.
  • The solution should be implemented entirely in Go.
  • The middleware should not significantly impact the performance of typical web requests (i.e., avoid computationally intensive operations within the logging logic itself).

Notes

  • Recall how http.Handler and http.HandlerFunc work in Go.
  • The http.Request struct contains all the necessary information for logging.
  • Consider using time.Now().Format() for consistent timestamp formatting.
  • The net.RemoteAddr field of http.Request will contain the client's IP address and port. You might want to parse this to get just the IP.
  • Think about how to chain middleware – your logging middleware should be able to wrap another handler, which might itself be a middleware.
Loading editor...
go