Course contentsShow
← Node.js
Lesson 1674 of 1,98015. Logging, Observability, and MetricsFree lesson

Building a Custom Logging Middleware

Construct a reusable HTTP middleware that captures request start, duration, and completion status.

In this lesson, you will learn how to build a reusable middleware component that captures the lifecycle of an HTTP request, including its duration and final status, to provide deep observability into your API’s performance.

The Lifecycle Middleware Pattern

In Node.js web frameworks like Express or Fastify, a logging middleware functions as a "wrapper" around the request-response cycle. Because we want to measure the time it takes for a request to complete, we must calculate the duration by capturing a timestamp when the request arrives and another when the response is finalized.

To achieve this, we hook into the finish or close events emitted by the response object. This ensures that no matter how the request ends—whether it succeeds or errors out—our logging logic triggers consistently.

Implementation Concept

Here is how you can implement a standard logging middleware:

const requestLogger = (req, res, next) => {
  const startTime = process.hrtime();

  res.on('finish', () => {
    const diff = process.hrtime(startTime);
    const durationInMs = (diff[0] * 1e3 + diff[1] * 1e-6).toFixed(3);

    // Structured logging object
    const logEntry = {
      method: req.method,
      path: req.originalUrl,
      status: res.statusCode,
      duration: `${durationInMs}ms`,
      timestamp: new Date().toISOString()
    };

    console.log(JSON.stringify(logEntry));
  });

  next();
};

Why This Matters

By placing this middleware at the top of your stack, you gain an automated performance baseline for every route in your application. Using process.hrtime() is critical here; unlike Date.now(), it provides high-resolution timing unaffected by system clock adjustments, making it the industry standard for measuring interval latency.

Because we are emitting a JSON object, this middleware integrates perfectly with the log aggregation patterns and structured data standards we covered in previous modules. It transforms raw traffic into searchable, actionable telemetry, allowing you to identify slow-performing endpoints before they impact your users.

Key Takeaway: By capturing the time delta between request initiation and finish completion, you create a self-documenting pipeline that turns every incoming request into a measurable data point for observability.