In this lesson, you will learn how to build a centralized logging utility to capture timing, status codes, and user identity for every incoming request.
Why Centralized Logging Matters
As your server grows, debugging issues becomes impossible if you have to hunt through scattered console.log statements inside individual route handlers. By implementing a centralized logger, you move the responsibility of tracking request health into a single, reusable component. This allows you to monitor how long each request takes (performance), what the server returned (accuracy), and who made the request (accountability).
Implementing the Utility
The cleanest way to achieve this is to wrap your request-handling logic in a function that intercepts the res.on('finish', ...) event. This event triggers once the response has been fully sent to the client, providing you with the final status code and the duration of the request.
function requestLogger(req, res, next) {
const startTime = Date.now();
// Attach user ID if available (from your Authentication Interceptor)
const userId = req.user ? req.user.id : 'anonymous';
res.on('finish', () => {
const duration = Date.now() - startTime;
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} ` +
`- Status: ${res.statusCode} - Duration: ${duration}ms - User: ${userId}`);
});
next();
}
Key Considerations
- Timing: By recording
Date.now()at the start and subtracting it inside thefinishlistener, you get an accurate metric of your server’s response time. - Context: Since this runs as middleware, it has access to the
reqobject, allowing you to extract dynamic parameters or headers injected by earlier layers like authentication or routing. - Non-blocking: Because we are using an event listener (
res.on('finish')), our logging logic executes only after the primary response has been handled, ensuring the logging utility doesn't delay the user’s experience.
By funneling every request through this utility, you create a standardized "audit trail" that makes performance profiling and troubleshooting significantly more predictable across your entire application.
Key Takeaway: Centralized logging uses the finish event to capture the lifecycle of a request in one location, decoupling diagnostic tracking from your business logic.