Skip to main content

Quick Start

This guide will help you get HTTP Ledger up and running in your Express application in just a few minutes.

Basic Setup

1

Install the package

First, install HTTP Ledger using your preferred package manager:
npm install http-ledger
2

Import the middleware

Import HTTP Ledger in your Express application:
const express = require('express');
const logger = require('http-ledger');
3

Add the middleware

Add the logger middleware to your Express app:
const app = express();

// Add body parsing middleware first
app.use(express.json());

// Add HTTP Ledger middleware
app.use(logger());

// Your routes go here
app.get('/', (req, res) => {
  res.json({ message: 'Hello World' });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
That’s it! HTTP Ledger will now log all requests and responses to your console.

Complete Working Example

Here’s a complete example that demonstrates HTTP Ledger’s key features:
const express = require('express');
const logger = require('http-ledger');

const app = express();

// Body parsing middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// HTTP Ledger with configuration
app.use(
  logger({
    // Basic logging options
    logBody: true,
    logResponse: true,
    logQueryParams: true,
    
    // Security: mask sensitive fields
    maskFields: ['password', 'token', 'apiKey'],
    
    // Security: exclude sensitive headers
    excludedHeaders: ['authorization', 'cookie'],
    
    // Request tracking
    autoGenerateRequestId: true,
    
    // Custom log level based on status code
    customLogLevel: (logData) => {
      if (logData.statusCode >= 500) return 'error';
      if (logData.statusCode >= 400) return 'warn';
      return 'info';
    },
    
    // Skip logging for health checks
    shouldLog: (req, res) => {
      return req.path !== '/health';
    }
  })
);

// Example routes
app.get('/', (req, res) => {
  res.json({ 
    message: 'Welcome to HTTP Ledger demo',
    version: '1.0.0'
  });
});

app.get('/health', (req, res) => {
  res.json({ status: 'ok' });
});

app.get('/users', (req, res) => {
  const { page = 1, limit = 10 } = req.query;
  res.json({ 
    users: [
      { id: 1, name: 'John Doe', email: '[email protected]' },
      { id: 2, name: 'Jane Smith', email: '[email protected]' }
    ],
    pagination: { page, limit }
  });
});

app.post('/users', (req, res) => {
  const { name, email, password } = req.body;
  
  // Simulate user creation
  const newUser = {
    id: Math.floor(Math.random() * 1000),
    name,
    email,
    createdAt: new Date().toISOString()
  };
  
  res.status(201).json(newUser);
});

app.get('/error', (req, res) => {
  res.status(500).json({ error: 'Internal server error' });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

Example Log Output

When you make a request to your server, HTTP Ledger will output structured JSON logs:

GET Request Example

Request:
curl "http://localhost:3000/users?page=1&limit=10"
Log output:
{
  "method": "GET",
  "url": "/users?page=1&limit=10",
  "statusCode": 200,
  "timeTaken": 12.45,
  "requestSize": 0,
  "responseSize": 256,
  "timestamp": {
    "request": "2024-01-15T10:30:00.000Z",
    "response": "2024-01-15T10:30:00.012Z"
  },
  "headers": {
    "user-agent": "curl/7.68.0",
    "accept": "*/*",
    "host": "localhost:3000"
  },
  "queryParams": {
    "page": "1",
    "limit": "10"
  },
  "responseBody": {
    "users": [
      { "id": 1, "name": "John Doe", "email": "[email protected]" },
      { "id": 2, "name": "Jane Smith", "email": "[email protected]" }
    ],
    "pagination": { "page": "1", "limit": "10" }
  },
  "requestId": "req-1a2b3c4d5e6f",
  "userAgent": "curl/7.68.0",
  "requestContentType": undefined,
  "responseContentType": "application/json; charset=utf-8",
  "httpVersion": "1.1",
  "hostname": "localhost",
  "logLevel": "info"
}

POST Request Example with Masked Fields

Request:
curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Alice Johnson",
    "email": "[email protected]",
    "password": "supersecret123"
  }'
Log output:
{
  "method": "POST",
  "url": "/users",
  "statusCode": 201,
  "timeTaken": 23.67,
  "requestSize": 95,
  "responseSize": 128,
  "timestamp": {
    "request": "2024-01-15T10:31:00.000Z",
    "response": "2024-01-15T10:31:00.024Z"
  },
  "headers": {
    "content-type": "application/json",
    "user-agent": "curl/7.68.0",
    "accept": "*/*",
    "host": "localhost:3000",
    "content-length": "95"
  },
  "queryParams": {},
  "body": {
    "name": "Alice Johnson",
    "email": "[email protected]",
    "password": "***"
  },
  "responseBody": {
    "id": 789,
    "name": "Alice Johnson",
    "email": "[email protected]",
    "createdAt": "2024-01-15T10:31:00.024Z"
  },
  "requestId": "req-7g8h9i0j1k2l",
  "userAgent": "curl/7.68.0",
  "requestContentType": "application/json",
  "responseContentType": "application/json; charset=utf-8",
  "httpVersion": "1.1",
  "hostname": "localhost",
  "logLevel": "info"
}
Notice how the password field is masked with "***" in the log output, protecting sensitive data.

Advanced Configuration Examples

Production Environment

Optimized for production with minimal overhead:
app.use(
  logger({
    // Only log errors in production
    shouldLog: (req, res) => {
      if (process.env.NODE_ENV === 'production') {
        return res.statusCode >= 400;
      }
      return true;
    },
    
    // Don't log request/response bodies in production
    logBody: process.env.NODE_ENV !== 'production',
    logResponse: process.env.NODE_ENV !== 'production',
    
    // Sample 10% of requests in high-traffic production
    logSampling: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
    
    // Mask sensitive fields
    maskFields: ['password', 'token', 'apiKey', 'secret'],
    
    // Send logs to external service
    onLog: async (logData) => {
      if (logData.statusCode >= 400) {
        await fetch(process.env.LOG_ENDPOINT, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(logData)
        });
      }
    }
  })
);

With IP Geolocation

Add geographic information to your logs:
app.use(
  logger({
    getIpInfo: async (ip) => {
      try {
        const response = await fetch(`https://ipapi.co/${ip}/json/`);
        const data = await response.json();
        return {
          country: data.country_name,
          city: data.city,
          region: data.region,
          timezone: data.timezone
        };
      } catch (error) {
        return {};
      }
    }
  })
);

Custom Formatter

Add custom fields to your logs:
app.use(
  logger({
    customFormatter: (logData) => ({
      ...logData,
      environment: process.env.NODE_ENV,
      service: 'user-api',
      version: '1.0.0',
      isSlowRequest: logData.timeTaken > 1000,
      requestCategory: logData.method === 'GET' ? 'read' : 'write'
    })
  })
);

Testing Your Setup

1

Start your server

Run your Express application:
node app.js
2

Make a test request

Use curl or your browser to make a request:
curl http://localhost:3000/
3

Check the console output

You should see a formatted JSON log in your console with all request details.

Common Use Cases

Skip Health Checks

app.use(
  logger({
    shouldLog: (req, res) => !req.path.startsWith('/health')
  })
);

Log Only Errors

app.use(
  logger({
    shouldLog: (req, res) => res.statusCode >= 400
  })
);

Different Configs per Environment

const loggerConfig = process.env.NODE_ENV === 'production'
  ? {
      logBody: false,
      logResponse: false,
      logSampling: 0.1,
      shouldLog: (req, res) => res.statusCode >= 400
    }
  : {
      logBody: true,
      logResponse: true
    };

app.use(logger(loggerConfig));

Next Steps

Now that you have HTTP Ledger working, explore more advanced features:

Configuration Options

Learn about all available configuration options

Security Features

Set up field masking and header exclusion

Custom Logging

Create custom formatters and log levels

API Reference

Explore the complete API reference
For more examples and use cases, check the GitHub repository or the README file.

Build docs developers (and LLMs) love