outlet-postgres
PostgreSQL logging handler for the
outlet HTTP request/response
middleware. This crate implements the RequestHandler
trait from outlet to log
HTTP requests and responses to PostgreSQL with JSONB serialization for bodies.
Features high-performance async logging with automatic table creation and structured query support.
Quick Start
Add this to your Cargo.toml
:
[]
= "0.1.0"
= "0.1.0"
= "0.8"
= { = "1.0", = ["full"] }
= "0.5"
Basic usage:
use ;
use PostgresHandler;
use ;
use ServiceBuilder;
async
async
Database Schema
The handler automatically creates two tables:
http_requests
id
- Primary keycorrelation_id
- Links to corresponding responsetimestamp
- When the request was receivedmethod
- HTTP method (GET, POST, etc.)uri
- Full request URIheaders
- Request headers as JSONBbody
- Request body as JSONB (optional)body_parsed
- Whether the body was parsed as the supplied JSON-serde type (defaultserde_json::Value
) or not. If not, thebody
field is the base64-encoded binary data.created_at
- When the record was inserted
http_responses
id
- Primary keycorrelation_id
- Links to corresponding requesttimestamp
- When the response was sentstatus_code
- HTTP status codeheaders
- Response headers as JSONBbody
- Response body as JSONB (optional)body_parsed
- Whether the body was parsed as the supplied JSON-serde type (defaultserde_json::Value
) or not. If not, thebody
field is the base64-encoded binary data.duration_ms
- Request processing time in millisecondscreated_at
- When the record was inserted
Configuration
You can control what data is captured using RequestLoggerConfig
:
use RequestLoggerConfig;
// Capture everything (default)
let config = default;
// Only capture requests, not responses
let config = RequestLoggerConfig ;
// Headers only, no bodies
let config = RequestLoggerConfig ;
Example Queries
Once you're logging requests, you can query the data:
-- Find all POST requests
SELECT method, uri, timestamp
FROM http_requests
WHERE method = 'POST'
ORDER BY timestamp DESC;
-- Find slow requests (> 1 second)
SELECT r.method, r.uri, s.status_code, s.duration_ms
FROM http_requests r
JOIN http_responses s ON r.correlation_id = s.correlation_id
WHERE s.duration_ms > 1000
ORDER BY s.duration_ms DESC;
-- Search request bodies for specific content
SELECT r.uri, r.body, s.status_code
FROM http_requests r
JOIN http_responses s ON r.correlation_id = s.correlation_id
WHERE r.body @> '{"user_id": 123}';
-- Get response statistics by endpoint
SELECT
r.uri,
COUNT(*) as request_count,
AVG(s.duration_ms) as avg_duration_ms,
MIN(s.duration_ms) as min_duration_ms,
MAX(s.duration_ms) as max_duration_ms
FROM http_requests r
JOIN http_responses s ON r.correlation_id = s.correlation_id
GROUP BY r.uri
ORDER BY request_count DESC;
Running the Example
-
Set up PostgreSQL and create a database
-
Set the
DATABASE_URL
environment variable: -
Run the example:
-
Test the endpoints:
License
MIT