Overview
Configuring HTTP Ledger for production requires balancing comprehensive logging with performance and security. This guide covers best practices for production deployments.
Production Configuration
Configure for production
const express = require ( 'express' );
const logger = require ( 'http-ledger' );
const app = express ();
app . use (
logger ({
// Disable verbose logging in production
logBody: process . env . NODE_ENV === 'development' ,
logResponse: process . env . NODE_ENV === 'development' ,
// Mask sensitive fields
maskFields: [ 'password' , 'token' , 'secret' , 'apiKey' ],
// Sample logs in high-traffic environments
logSampling: process . env . NODE_ENV === 'production' ? 0.1 : 1.0 ,
// Custom log levels
customLogLevel : ( logData ) => {
if ( logData . statusCode >= 500 ) return 'error' ;
if ( logData . statusCode >= 400 ) return 'warn' ;
return 'info' ;
},
// Send to external logging service
onLog : async ( logData ) => {
await fetch ( process . env . LOG_ENDPOINT , {
method: 'POST' ,
body: JSON . stringify ( logData ),
headers: { Authorization: `Bearer ${ process . env . LOG_API_KEY } ` },
});
},
}),
);
app . listen ( 3000 );
Set environment variables
NODE_ENV = production
LOG_ENDPOINT = https://your-logging-service.com/api/logs
LOG_API_KEY = your-api-key-here
Security Best Practices
Field Masking
Always mask sensitive data to prevent exposure in logs:
app . use (
logger ({
maskFields: [
'password' ,
'token' ,
'secret' ,
'apiKey' ,
'creditCard' ,
'ssn' ,
'authorization' ,
],
}),
);
Nested field masking is supported:
app . use (
logger ({
maskFields: [ 'user.password' , 'data.secret' , 'nested.deep.secret' ],
}),
);
Exclude sensitive headers from logs:
app . use (
logger ({
excludedHeaders: [ 'authorization' , 'cookie' , 'x-api-key' , 'x-auth-token' ],
}),
);
Log Sampling
Reduce logging overhead in high-traffic environments:
High Traffic
Medium Traffic
Full Logging
app . use (
logger ({
logSampling: 0.1 , // Log 10% of requests
}),
);
Selective Logging
Skip logging for specific endpoints:
app . use (
logger ({
shouldLog : ( req , res ) => {
// Skip health check endpoints
if ( req . path === '/health' || req . path === '/ping' ) return false ;
// Skip successful GET requests to static files
if (
req . method === 'GET' &&
req . path . startsWith ( '/static/' ) &&
res . statusCode === 200
) {
return false ;
}
// Skip OPTIONS requests
if ( req . method === 'OPTIONS' ) return false ;
return true ;
},
}),
);
Disable Body Logging
For large payloads or high-traffic APIs:
app . use (
logger ({
logBody: false ,
logResponse: false ,
logQueryParams: true , // Still log query params
}),
);
External Service Integration
Centralized Logging
Send logs to external services like Datadog, Loggly, or custom endpoints:
app . use (
logger ({
onLog : async ( logData ) => {
try {
// Send to external logging service
await fetch ( process . env . LOG_ENDPOINT , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
Authorization: `Bearer ${ process . env . LOG_API_KEY } ` ,
},
body: JSON . stringify ( logData ),
});
} catch ( error ) {
// Fallback: log to console if external service fails
console . error ( 'Failed to send logs to external service:' , error );
}
},
}),
);
Database Logging
Store logs in a database for analysis:
const { MongoClient } = require ( 'mongodb' );
const client = new MongoClient ( process . env . MONGODB_URI );
app . use (
logger ({
onLog : async ( logData ) => {
try {
const db = client . db ( 'logs' );
await db . collection ( 'api_logs' ). insertOne ({
... logData ,
insertedAt: new Date (),
});
} catch ( error ) {
console . error ( 'Failed to insert log into database:' , error );
}
},
}),
);
Request Tracking
Enable request ID generation for distributed tracing:
app . use (
logger ({
autoGenerateRequestId: true ,
}),
);
This automatically:
Generates a UUID v4 if X-Request-ID header is not present
Adds the request ID to response headers
Includes the request ID in log output
Add environment and service metadata:
app . use (
logger ({
customFormatter : ( logData ) => ({
... logData ,
environment: process . env . NODE_ENV ,
service: process . env . SERVICE_NAME || 'api' ,
version: process . env . APP_VERSION ,
region: process . env . AWS_REGION ,
// Add custom metrics
isSlowRequest: logData . timeTaken > 1000 ,
requestCategory: logData . method === 'GET' ? 'read' : 'write' ,
}),
}),
);
Complete Production Example
const express = require ( 'express' );
const logger = require ( 'http-ledger' );
const app = express ();
app . use ( express . json ());
app . use (
logger ({
// Security
maskFields: [ 'password' , 'token' , 'secret' , 'apiKey' , 'creditCard' ],
excludedHeaders: [ 'authorization' , 'cookie' , 'x-api-key' ],
// Performance
logBody: process . env . NODE_ENV === 'development' ,
logResponse: process . env . NODE_ENV === 'development' ,
logSampling: process . env . LOG_SAMPLING_RATE || 0.1 ,
shouldLog : ( req , res ) => {
if ( req . path === '/health' ) return false ;
if ( req . method === 'OPTIONS' ) return false ;
return true ;
},
// Tracking
autoGenerateRequestId: true ,
// Custom formatting
customLogLevel : ( logData ) => {
if ( logData . statusCode >= 500 ) return 'error' ;
if ( logData . statusCode >= 400 ) return 'warn' ;
if ( logData . timeTaken > 1000 ) return 'warn' ;
return 'info' ;
},
customFormatter : ( logData ) => ({
... logData ,
environment: process . env . NODE_ENV ,
service: process . env . SERVICE_NAME ,
version: process . env . APP_VERSION ,
}),
// External integration
onLog : async ( logData ) => {
if ( process . env . LOG_ENDPOINT ) {
try {
await fetch ( process . env . LOG_ENDPOINT , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
Authorization: `Bearer ${ process . env . LOG_API_KEY } ` ,
},
body: JSON . stringify ( logData ),
});
} catch ( error ) {
console . error ( 'Failed to send logs:' , error );
}
}
},
}),
);
const PORT = process . env . PORT || 3000 ;
app . listen ( PORT , () => {
console . log ( `Server running on port ${ PORT } ` );
});
Environment Variables
Variable Description Example NODE_ENVApplication environment productionLOG_ENDPOINTExternal logging service URL https://logs.example.com/apiLOG_API_KEYAPI key for logging service sk_live_xxxxxLOG_SAMPLING_RATEPercentage of requests to log 0.1 (10%)SERVICE_NAMEName of the service user-apiAPP_VERSIONApplication version 1.0.0
The middleware includes graceful error handling - if onLog throws an error, logging continues normally and the error is logged to console.