Menu

Automatically Logging Errors in Express with Pino

Automatically Logging Errors in Express with Pino

Introduction

Logging errors is crucial for debugging and monitoring your Express.js applications. While Pino is known for its high-performance logging, it doesn’t automatically log errors unless explicitly configured. In this guide, we’ll walk through a simple method to automatically capture and log errors using pino-http in Express.

Step 1: Install Pino and Pino-HTTP

First, install the required dependencies:

npm install pino pino-http

Step 2: Set Up Pino-HTTP Middleware

To log incoming requests and responses, use pino-http as middleware:

const express = require('express');
const pino = require('pino');
const pinoHttp = require('pino-http');

const logger = pino({
  level: 'info', // Set log level
  transport: {
    target: 'pino-pretty' // Optional: Pretty-print logs during development
  }
});

const app = express();

// Apply Pino-HTTP middleware for logging requests
app.use(pinoHttp({ logger }));

Now, every incoming request will be logged automatically in a structured JSON format. By default, Pino logs output to the console, but you can configure it to write logs to a file (explained below).

Step 3: Automatically Log Errors

To capture and log errors, add an error-handling middleware at the end of the middleware chain:

app.use((err, req, res, next) => {
  req.log.error({
    message: err.message,
    stack: err.stack,
    status: res.statusCode
  }, 'Unhandled error occurred');
  res.status(500).send('Internal Server Error');
});

How Errors Are Logged

This middleware does two things:

  1. Logs the error details using req.log.error, including the message, stack trace, and response status.
  2. Sends a 500 Internal Server Error response to the client.

By default, these logs appear in the console, but they can be redirected to a file.

Example of a logged error:

{
  "level": 50,
  "time": 1672028160000,
  "pid": 1234,
  "hostname": "localhost",
  "msg": "Unhandled error occurred",
  "message": "Something went wrong!",
  "stack": "Error: Something went wrong! at ...",
  "status": 500
}

Step 4: Writing Logs to a File

If you want to save logs to a file instead of just displaying them in the console, you can create a writable stream:

const fs = require('fs');
const logStream = fs.createWriteStream('./logs.log', { flags: 'a' });
const logger = pino(logStream);

Now, all logs will be written to logs.log.

Alternatively, you can run the app and redirect logs to a file:

node app.js > logs.log 2>&1

This will save all logs, including errors, to logs.log.

Step 5: Testing Error Logging

Add a test route that intentionally throws an error:

app.get('/error', (req, res, next) => {
  next(new Error('Something went wrong!'));
});

Run your server and make a request to /error. You should see an error log similar to the example above, either in the console or in the log file (if configured).

Configuring Pino for Different Environments

You can adjust Pino configurations based on the environment:

const logger = pino({
  level: process.env.NODE_ENV === 'production' ? 'error' : 'debug',
  transport: process.env.NODE_ENV !== 'production' ? { target: 'pino-pretty' } : undefined
});
  • Production: Logs only error level messages.
  • Development: Uses pino-pretty for human-readable logs.

Conclusion

With just a few lines of code, you can automatically log errors in your Express app using Pino. By default, logs are printed to the console, but they can also be saved to a file for persistent storage.

Now, every unexpected error will be captured and logged efficiently, complete with configurations for different environments. Happy coding! 🚀

Walter Guevara is a Computer Scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.
AD: "Heavy scripts slowing down your site? I use Fathom Analytics because it’s lightweight, fast, and doesn’t invade my users privacy." - Get $10 OFF your first invoice.

Community Comments

No comments posted yet

Code Your Own Classic Snake Game – The Right Way

Master the fundamentals of game development and JavaScript with a step-by-step guide that skips the fluff and gets straight to the real code.

Ad Unit

Current Poll

Help us and the community figure out what the latest trends in coding are.

Total Votes:
Q:
Submit

Add a comment