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
Entry Fields
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