home Tutorial Node.js API Logging Middleware: Log, Audit, and Debug with Ease

Node.js API Logging Middleware: Log, Audit, and Debug with Ease

Node.js API Logging Middleware is the unsung hero you didn’t know you needed—until your code starts misbehaving and the blame game begins with your unsuspecting third-party API. Of course you’ve been there—it’s practically a developer rite of passage. I certainly was, staring at my screen as the system acted erratically thanks to cryptic responses from an external service. The logs? Useless. My patience? Gone. So, like any over-caffeinated developer on a mission, I built one myself.

Introducing the Node.js API Logging Middleware, a delightful little npm package born out of frustration and caffeine. With this handy tool, you can effortlessly log your API calls along with their responses directly into MongoDB, making auditing a walk in the park.

Why Did I Build This?

Let’s rewind a bit: A client reported an issue. My team scratched heads. My logs shrugged helplessly. It was one of those classic “it works on my machine” scenarios. The usual suspects (network issues, incorrect handling, mischievous elves) were quickly ruled out. We needed more visibility. We needed a way to record every interaction meticulously. We needed… well, this logger.

Features That Make It Shine

  • Logs API URL, method, request/response data, status, user info, timestamps, and duration
  • Mask sensitive fields (e.g., password, token)
  • Configurable via options (MongoDB URI, collection, etc.)
  • Express middleware support
  • NestJS middleware support
  • TypeScript support
  • Filter by routes, methods, status codes
  • Custom user info extraction
  • Response body logging (configurable)

Installation

npm install git+https://github.com/rick001/api-logger-mongodb.git
# or
yarn add git+https://github.com/rick001/api-logger-mongodb.git

Use Cases with Example Code

Express.js – Quick Start

import express from 'express';
import { apiLoggerExpress } from 'api-logger-mongodb';

const app = express();
app.use(express.json());

app.use(apiLoggerExpress({
  mongoUri: 'mongodb://localhost:27017',
  databaseName: 'my_logs',
  collectionName: 'api_audit',
  maskFields: ['password', 'token'],
  logResponseBody: true,
  logRequestBody: true,
  getUserInfo: req => req.user ? { id: req.user.id, email: req.user.email } : undefined
}));

app.get('/api/users', (req, res) => {
  res.json({ users: [] });
});

app.listen(3000);

NestJS – Apply Middleware

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { createApiLoggerMiddleware } from 'api-logger-mongodb';

@Module({})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(createApiLoggerMiddleware({
        mongoUri: 'mongodb://localhost:27017',
        databaseName: 'my_nestjs_logs',
        collectionName: 'api_audit',
        maskFields: ['password', 'token'],
        logResponseBody: true,
        logRequestBody: true,
        getUserInfo: (req) => {
          const user = (req as any).user;
          return user ? { id: user.id, email: user.email, role: user.role } : undefined;
        }
      }))
      .forRoutes('*');
  }
}

Standalone (Axios / Fetch / Other Clients)

import axios from 'axios';
import { StandaloneApiLogger, createAxiosLogger } from 'api-logger-mongodb';

const logger = new StandaloneApiLogger({
  mongoUri: 'mongodb://localhost:27017',
  databaseName: 'my_logs',
  collectionName: 'api_audit',
  maskFields: ['password', 'token'],
  logResponseBody: true,
  logRequestBody: true
});

await logger.init();

const axiosLogger = createAxiosLogger(logger, () => ({ id: 'user123', email: '[email protected]' }));
axios.interceptors.request.use(axiosLogger.request);
axios.interceptors.response.use(axiosLogger.response, axiosLogger.error);

const response = await axios.get('https://api.example.com/users');

Manual Logging

await logger.logRequest(
  'https://api.example.com/users',
  'GET',
  {
    headers: { 'Authorization': 'Bearer token' },
    query: { page: 1 }
  },
  {
    statusCode: 200,
    body: { users: [] }
  },
  { id: 'user123', email: '[email protected]' },
  150
);

Advanced Usage – Filter Routes and Methods (Express)

app.use(apiLoggerExpress({
  mongoUri: 'mongodb://localhost:27017',
  databaseName: 'my_logs',
  collectionName: 'api_audit',
  maskFields: ['password', 'token'],
  includeRoutes: [/^\/api\/users/, /^\/api\/orders/],
  excludeRoutes: [/^\/health/, /^\/metrics/],
  includeMethods: ['POST', 'PUT', 'DELETE'],
  logErrorsOnly: true
}));

MongoDB Query Examples

// Failed requests
db.api_audit.find({ "response.statusCode": { $gte: 400 } });

// Slow requests (> 1 second)
db.api_audit.find({ durationMs: { $gt: 1000 } });

// Requests by user ID
db.api_audit.find({ "user.id": "1234" });

// Requests in the last hour
db.api_audit.find({ createdAt: { $gte: new Date(Date.now() - 3600000) } });

// Aggregated usage
db.api_audit.aggregate([
  { $group: { _id: "$url", count: { $sum: 1 } } },
  { $sort: { count: -1 } }
]);

Log Schema Example

{
  "url": "/api/users",
  "method": "POST",
  "request": {
    "headers": {},
    "body": {},
    "query": {},
    "params": {}
  },
  "response": {
    "statusCode": 200,
    "body": {}
  },
  "user": {
    "id": "1234",
    "email": "[email protected]"
  },
  "createdAt": "2025-07-01T10:00:00Z",
  "durationMs": 145,
  "ip": "127.0.0.1",
  "userAgent": "Mozilla/5.0 ..."
}

Real-Life Scenario: Saved by the Logger

Remember that cryptic third-party API response? With this logger in action, I discovered the sneaky issue—our “friendly” API was randomly altering response formats at night. Mystery solved, and I had all the data to confidently say, “See, it wasn’t me!”

Want to Try It?

Head over to the Node.js API Logging Middleware repository, star it (if you’re into that sort of thing), and give it a spin. Don’t let missing logs steal your weekend again.

Stay bug-free, folks! And remember: log first, debug later.

Leave a Reply