Function Signature
const logger = (options?: ApiLoggerOptions) => (req: Request, res: Response, next: NextFunction) => void
Description
The logger function is the main Express middleware for comprehensive API request and response logging. It captures detailed information about HTTP requests and responses including method, URL, status code, response time, request/response sizes, headers, query parameters, bodies, and IP information.
Parameters
options
ApiLoggerOptions
default:"{}"
Configuration options for the logger middleware. See ApiLoggerOptions for detailed documentation of all available options.
Returns
middleware
(req: Request, res: Response, next: NextFunction) => void
An Express middleware function that can be used with app.use() or route-specific handlers.
Basic Usage
import express from 'express';
import logger from 'http-ledger-express';
const app = express();
// Use with default options
app.use(logger());
// Your routes
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.listen(3000);
Advanced Usage
Custom Logging Options
import logger from 'http-ledger-express';
app.use(logger({
logBody: true,
logResponse: true,
logQueryParams: true,
excludedHeaders: ['authorization', 'cookie'],
maskFields: ['password', 'token', 'apiKey']
}));
With IP Geolocation
import logger from 'http-ledger-express';
import geoip from 'geoip-lite';
app.use(logger({
getIpInfo: async (ip: string) => {
const geo = geoip.lookup(ip);
return {
ip,
country: geo?.country,
region: geo?.region,
city: geo?.city,
timezone: geo?.timezone
};
}
}));
Custom Log Handling
import logger from 'http-ledger-express';
import { sendToAnalytics } from './analytics';
app.use(logger({
onLog: async (logData) => {
// Send to external analytics service
await sendToAnalytics(logData);
// Store in database
await db.logs.insert(logData);
}
}));
Conditional Logging
import logger from 'http-ledger-express';
app.use(logger({
// Only log errors and slow requests
shouldLog: (req, res) => {
return res.statusCode >= 400 || res.getHeader('X-Response-Time') > 1000;
},
// Sample 10% of requests
logSampling: 0.1
}));
import logger from 'http-ledger-express';
app.use(logger({
customLogLevel: (logData) => {
if (logData.error) return 'error';
if (logData.statusCode >= 400) return 'warn';
return 'info';
},
customFormatter: (logData) => {
return {
...logData,
environment: process.env.NODE_ENV,
appVersion: process.env.APP_VERSION,
timestamp: new Date().toISOString()
};
}
}));
Auto-Generate Request IDs
import logger from 'http-ledger-express';
app.use(logger({
autoGenerateRequestId: true
}));
// Request ID will be added to response headers as 'X-Request-ID'
// and included in log data
Default Options
When no options are provided, the logger uses these defaults:
{
logBody: true,
logResponse: true,
logQueryParams: true,
excludedHeaders: []
}
The middleware logs data in JSON format with the following structure. See LogData for complete documentation:
{
"method": "GET",
"url": "/api/users",
"statusCode": 200,
"timeTaken": 45.23,
"requestSize": 0,
"responseSize": 1024,
"timestamp": {
"request": "2024-03-20T10:30:00.000Z",
"response": "2024-03-20T10:30:00.045Z"
},
"headers": {
"user-agent": "Mozilla/5.0...",
"accept": "application/json"
},
"queryParams": {},
"responseBody": { "users": [] },
"userAgent": "Mozilla/5.0...",
"httpVersion": "1.1",
"hostname": "localhost",
"logLevel": "info"
}
Behavior
Response Capture
The middleware intercepts res.send() and res.end() to capture response bodies and timing information without interfering with normal response flow.
Event Listeners
Logs are emitted on these response events:
finish - Normal completion
close - Connection closed
error - Response error occurred
Logs are only emitted once, even if multiple events fire.
Error Handling
The middleware is designed to never break your application:
- Errors in custom functions (getIpInfo, onLog, customFormatter, etc.) are caught and logged as warnings
- If the main logging fails, a fallback error log is emitted with basic request information
- The middleware always calls
next() to continue the request chain
Excluded headers are normalized to lowercase for case-insensitive matching:
logger({
excludedHeaders: ['Authorization', 'COOKIE', 'X-Api-Key']
})
// Matches: 'authorization', 'cookie', 'x-api-key' (case-insensitive)
Sampling
For high-traffic applications, use sampling to reduce overhead:
logger({ logSampling: 0.1 }) // Log 10% of requests
Conditional Logging
Skip logging for health checks and static assets:
logger({
shouldLog: (req, res) => {
return !req.url.startsWith('/health') &&
!req.url.startsWith('/static');
}
})
Disable Body Logging
For large payloads, consider disabling body logging:
logger({
logBody: false,
logResponse: false
})
See Also