Overview
Theaudit middleware captures detailed information about every HTTP request for compliance, debugging, and security monitoring. It provides flexible handlers for storing audit logs.
Use it when you need:
- Compliance audit trails
- Security event logging
- Request debugging and analysis
Installation
Quick Start
Configuration
Options
| Option | Type | Default | Description |
|---|---|---|---|
Handler | func(*Entry) | Required | Callback for each entry |
Skip | func(*mizu.Ctx) bool | nil | Skip logging for requests |
IncludeRequestBody | bool | false | Include request body |
MaxBodySize | int | 1024 | Max body size to capture |
Metadata | func(*mizu.Ctx) map[string]string | nil | Custom metadata |
Entry Fields
| Field | Type | Description |
|---|---|---|
Timestamp | time.Time | Request time |
Method | string | HTTP method |
Path | string | Request path |
Query | string | Query string |
Status | int | Response status |
Latency | time.Duration | Request duration |
IP | string | Client IP |
UserAgent | string | User-Agent header |
RequestID | string | X-Request-ID header |
RequestBody | string | Request body (if enabled) |
Metadata | map[string]string | Custom metadata |
Examples
Basic Logging
With Request Body
Skip Health Checks
With Custom Metadata
Channel Handler (Async)
Buffered Handler (Batch)
API Reference
Functions
BufferedHandler Methods
Technical Details
Implementation Architecture
The audit middleware is built around a flexible handler pattern that processes audit entries containing comprehensive request/response metadata.Core Components
Entry Structure: TheEntry type captures all relevant information about an HTTP request/response cycle:
- Request metadata (timestamp, method, path, query, remote address, user agent)
- Request identification (request ID from configurable header)
- Optional request body capture with size limits
- Response status and latency measurement
- Error information if handler returns an error
- Custom metadata extension point
auditResponseWriter that wraps the standard http.ResponseWriter to capture the response status code. This wrapper intercepts WriteHeader and Write calls to record the status, defaulting to 200 OK if not explicitly set.
Request Body Capture: When enabled, the middleware reads the request body up to MaxBodySize using io.LimitReader, then restores it using io.MultiReader so downstream handlers can still access it. This ensures body capture doesnβt interfere with normal request processing.
Timing Measurement: Latency is calculated by recording the start time before calling the next handler and computing the elapsed duration after it returns. This provides accurate end-to-end request processing time.
Handler Patterns
Synchronous Handler: The basic handler function receives each entry immediately and processes it in the request path. Suitable for logging to stdout or fast operations. Channel Handler: Sends entries to a buffered channel for asynchronous processing. Uses a non-blocking select with default case to drop entries if the channel is full, preventing request blocking. Buffered Handler: Collects entries in memory and flushes them in batches either when reachingmaxSize or on a timer interval. Includes proper mutex protection for concurrent access and a background goroutine for periodic flushing.
Configuration Defaults
RequestIDHeader: βX-Request-IDβMaxBodySize: 1024 bytesHandler: Defaults to encoding JSON toio.Discardif not specifiedIncludeRequestBody: false (opt-in for performance and privacy)
Best Practices
- Use async handlers for high-traffic applications
- Set reasonable
MaxBodySizeto prevent memory issues - Skip logging for health checks and metrics endpoints
- Include request IDs for correlation with other logs
- Buffer writes for database storage
Testing
The audit middleware includes comprehensive test coverage for all functionality:| Test Case | Description | Expected Behavior |
|---|---|---|
TestNew | Basic middleware creation with handler | Captures all entry fields (method, path, query, user agent, request ID, status, latency) correctly |
TestWithOptions_RequestBody | Request body capture with size limit | Reads and stores request body up to MaxBodySize, body remains readable by handler |
TestWithOptions_Skip | Conditional logging with skip function | Skips audit logging for matched requests (/health), logs others normally |
TestWithOptions_Metadata | Custom metadata injection | Adds custom key-value pairs to entry metadata via callback function |
TestWithOptions_Error | Error handling and status capture | Records error status codes (500) correctly when handler returns error |
TestChannelHandler | Async channel-based handler | Sends entries to channel without blocking request processing |
TestBufferedHandler | Batch processing with size trigger | Buffers entries and flushes when batch size (3) is reached |
TestBufferedHandler_Flush | Manual flush operation | Immediately flushes buffered entries when Flush() is called |
TestBufferedHandler_Handler | Handler function retrieval | Returns valid handler function for middleware integration |