Overview
Thelogger middleware logs HTTP requests with configurable format, output destination, and filtering. It captures method, path, status, latency, and custom fields.
Use it when you need:
- HTTP request logging
- Access logs for debugging
- Request timing metrics
Installation
Quick Start
Configuration
Options
| Option | Type | Default | Description |
|---|---|---|---|
Output | io.Writer | os.Stdout | Log output destination |
Format | string | Default format | Log format template |
Skip | func(*mizu.Ctx) bool | nil | Skip logging for requests |
Format Tags
| Tag | Description |
|---|---|
${method} | HTTP method |
${path} | Request path |
${status} | Response status code |
${latency} | Request duration |
${ip} | Client IP address |
${host} | Request host |
${protocol} | HTTP protocol |
${referer} | Referer header |
${user_agent} | User-Agent header |
${bytes_out} | Response size |
${query} | Query string |
${header:X-Name} | Custom header value |
Examples
Default Logger
Custom Format
JSON Format
Write to File
Skip Health Checks
Include Request ID
Full Access Log
API Reference
Functions
Technical Details
Implementation Architecture
The logger middleware captures HTTP request metrics by wrapping the response writer and measuring execution time:-
Response Writer Wrapping: A custom
responseWritertype wraps the standardhttp.ResponseWriterto capture:- HTTP status code (defaults to 200)
- Response size in bytes
-
Timing Measurement: Uses
time.Now()before request processing andtime.Since()after to calculate latency with nanosecond precision. -
Client IP Detection: Implements intelligent IP extraction with fallback chain:
- Checks
X-Forwarded-Forheader (uses first IP if comma-separated list) - Checks
X-Real-IPheader - Falls back to
RemoteAddrfrom the request
- Checks
-
Format String Processing: The
formatLogfunction performs template tag replacement:- Basic tags use
strings.ReplaceAll()for simple substitution - Dynamic tags (
${header:name},${form:name}) use index-based parsing to extract custom values - Supports all standard HTTP request/response attributes
- Basic tags use
- Skip Function: Optional predicate function allows conditional logging based on request context, executed before timing starts to avoid overhead.
Performance Characteristics
- Minimal overhead: Single writer wrap and string replacement operations
- Zero allocations for skipped requests
- String concatenation deferred until after request completion
- No buffering of response body (streaming-friendly)
Best Practices
- Skip logging for health check endpoints
- Use structured (JSON) format for log aggregation
- Include request IDs for tracing
- Log to stderr in containers for proper log handling
Testing
The logger middleware includes comprehensive test coverage for all features and edge cases:| Test Case | Description | Expected Behavior |
|---|---|---|
TestNew | Default logger with standard output | Logs contain status code (200), HTTP method (GET), and request path (/test) |
TestWithOptions_CustomFormat | Custom format string with method, path, and status | Output matches exact format: [GET] /api -> 201\n |
TestWithOptions_Skip | Skip function filtering health check endpoint | No log output for /health endpoint, logs /api endpoint normally |
TestWithOptions_Headers | Custom header extraction using ${header:X-Request-ID} | Logs the exact value of the X-Request-ID header (test-123) |
TestWithOptions_AllTags | All available format tags (host, protocol, referer, user_agent, bytes_out, query) | Log contains all requested tag values from the HTTP request |
TestWithOptions_XForwardedFor | Client IP extraction from X-Forwarded-For header | Extracts first IP from comma-separated list (1.2.3.4) |
TestWithOptions_XRealIP | Client IP extraction from X-Real-IP header | Uses X-Real-IP value (10.0.0.1) when X-Forwarded-For not present |
TestDefaultOutput | Default output configuration (stdout) | Middleware executes without panic, returns 200 status |
Related Middlewares
- requestid - Request ID generation
- requestlog - Detailed request logging
- audit - Audit logging
- timing - Server-Timing header