Overview
The ApiLoggerOptions interface defines all configuration options available for customizing the behavior of the HTTP Ledger Express middleware. These options control what data is logged, how itβs processed, and when logging occurs.
Interface Definition
import { Request, Response } from 'express';
import { IpInfo, LogData, LogLevel } from '@httpledger/express';
interface ApiLoggerOptions {
logBody?: boolean;
logResponse?: boolean;
logQueryParams?: boolean;
excludedHeaders?: string[];
getIpInfo?: (ip: string) => Promise<IpInfo>;
onLog?: (logData: LogData) => void | Promise<void>;
maskFields?: string[];
customLogLevel?: (logData: LogData) => LogLevel;
customFormatter?: (logData: LogData) => unknown;
autoGenerateRequestId?: boolean;
shouldLog?: (req: Request, res: Response) => boolean;
logSampling?: number;
}
Properties
Whether to log the request body. When enabled, the request body will be included in the log data.
Whether to log the response body. When enabled, the response body will be included in the log data.
Whether to log query parameters from the request URL. When disabled, query parameters will be excluded from logs.
List of header names to exclude from logs. Header matching is case-insensitive. Useful for excluding sensitive headers like Authorization or Cookie.Example: ['authorization', 'cookie', 'x-api-key']
getIpInfo
(ip: string) => Promise<IpInfo>
Optional async function to enrich logs with IP geolocation information. Receives the client IP address and should return an IpInfo object.Example:async (ip: string) => {
const response = await fetch(`https://ipapi.co/${ip}/json/`);
return response.json();
}
onLog
(logData: LogData) => void | Promise<void>
Optional callback function that receives the complete log data for each request. Can be used to send logs to external services, databases, or custom logging systems.Example:async (logData: LogData) => {
await sendToDatadog(logData);
}
List of field names to mask in request/response bodies, headers, and query parameters. Masked fields will show [REDACTED] instead of their actual values.Example: ['password', 'creditCard', 'ssn']
customLogLevel
(logData: LogData) => LogLevel
Custom function to determine the log level based on the log data. Receives the complete LogData object and should return 'info', 'warn', or 'error'.Example:(logData: LogData) => {
if (logData.statusCode >= 500) return 'error';
if (logData.statusCode >= 400) return 'warn';
return 'info';
}
customFormatter
(logData: LogData) => unknown
Custom function to format or transform the log data before itβs logged. Receives the complete LogData object and can return any structure.Example:(logData: LogData) => ({
timestamp: logData.timestamp.request,
request: `${logData.method} ${logData.url}`,
status: logData.statusCode,
duration: `${logData.timeTaken}ms`
})
Whether to automatically generate a request ID if one is not present in the request headers. The generated ID will be a UUID v4.
shouldLog
(req: Request, res: Response) => boolean
Function to conditionally determine whether to log a specific request. Receives the Express request and response objects. Return false to skip logging.Example:(req: Request, res: Response) => {
// Don't log health check endpoints
return req.path !== '/health';
}
Sampling rate for logging requests, expressed as a decimal between 0 and 1. For example, 0.1 means log 10% of requests, 0.5 means log 50%.Example: 0.1 (log 10% of requests)
Usage Examples
Basic Configuration
import express from 'express';
import { httpLedger, ApiLoggerOptions } from '@httpledger/express';
const app = express();
const options: ApiLoggerOptions = {
logBody: true,
logResponse: true,
excludedHeaders: ['authorization', 'cookie']
};
app.use(httpLedger(options));
Advanced Configuration with Custom Handlers
import { httpLedger, ApiLoggerOptions, LogData, IpInfo } from '@httpledger/express';
const options: ApiLoggerOptions = {
logBody: true,
logResponse: false,
logQueryParams: true,
excludedHeaders: ['authorization', 'x-api-key'],
maskFields: ['password', 'creditCard', 'ssn'],
autoGenerateRequestId: true,
// Add IP geolocation
getIpInfo: async (ip: string): Promise<IpInfo> => {
try {
const response = await fetch(`https://ipapi.co/${ip}/json/`);
return await response.json();
} catch (error) {
return { ip };
}
},
// Custom log handler
onLog: async (logData: LogData) => {
// Send to external logging service
await fetch('https://logs.example.com/api/logs', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(logData)
});
},
// Custom log level determination
customLogLevel: (logData: LogData) => {
if (logData.error) return 'error';
if (logData.statusCode >= 500) return 'error';
if (logData.statusCode >= 400) return 'warn';
if (logData.timeTaken > 5000) return 'warn';
return 'info';
},
// Conditional logging
shouldLog: (req, res) => {
// Skip health checks and metrics endpoints
const skipPaths = ['/health', '/metrics', '/ping'];
return !skipPaths.includes(req.path);
},
// Log only 25% of requests
logSampling: 0.25
};
app.use(httpLedger(options));
Production-Ready Configuration
import { httpLedger, ApiLoggerOptions } from '@httpledger/express';
import { sendToDatadog } from './monitoring';
const options: ApiLoggerOptions = {
logBody: process.env.NODE_ENV === 'development',
logResponse: false,
logQueryParams: true,
excludedHeaders: [
'authorization',
'cookie',
'x-api-key',
'x-auth-token'
],
maskFields: [
'password',
'token',
'secret',
'creditCard',
'ssn',
'apiKey'
],
autoGenerateRequestId: true,
onLog: async (logData) => {
await sendToDatadog(logData);
},
customLogLevel: (logData) => {
if (logData.statusCode >= 500) return 'error';
if (logData.statusCode >= 400) return 'warn';
return 'info';
},
shouldLog: (req) => {
return !req.path.startsWith('/internal/');
},
// In production, sample 10% of successful requests
logSampling: process.env.NODE_ENV === 'production' ? 0.1 : 1.0
};
app.use(httpLedger(options));
See Also
- LogData - The complete log data structure
- IpInfo - IP geolocation information structure
- LogLevel - Available log levels