javascript

Is Your Express App Ready for Pino, the Ferrari of Logging?

Embrace the Speed and Precision of Pino for Seamless Express Logging

Is Your Express App Ready for Pino, the Ferrari of Logging?

When diving into logging HTTP requests in Express applications, many developers lean towards Pino for its impressive speed and rich feature set. Pino is like the Ferrari of logging tools in the Node.js ecosystem – it’s fast, sleek, and reliable.

Why Go with Pino?

What sets Pino apart is its blazing speed. Time is crucial, especially for applications where performance is non-negotiable. Pino also boasts versatility, making it a great companion for various Node.js frameworks such as Express and Fastify.

Getting Started with Pino and Express

Let’s break it down on how you can set up Pino with an Express application.

First off, create a new directory for your project, then kick things off by initializing a new Node.js project.

mkdir pino-logging && cd pino-logging
npm init -y

Next, you’ll need to install Pino and pino-http, the latter being essential for HTTP request and response logging.

npm install pino pino-http --save

Now, you can roll up your sleeves and create your Express server. Here’s how you can integrate Pino logging into it:

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

const logger = pino();
const httpLogger = pinoHttp({ logger });

const app = express();

// Use Pino HTTP middleware
app.use(httpLogger);

app.get('/', (req, res) => {
  req.log.info('Home route accessed');
  res.send('Hello, World!');
});

app.get('/user/:id', (req, res) => {
  const userId = req.params.id;
  req.log.info({ userId }, 'User route accessed');
  res.send(`User ID: ${userId}`);
});

// Error handling middleware
app.use((err, req, res, next) => {
  req.log.error({ err }, 'Unhandled error');
  res.status(500).send('Something went wrong');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  logger.info(`Server is running on port ${PORT}`);
});

Logging HTTP Requests and Responses

When you make Pino log HTTP requests and responses, it gets pretty detailed – capturing HTTP methods, URLs, status codes, and response times.

Here’s what happens when a request hits your app. If someone does a GET request to the root URL, Pino generates a log entry that captures all these details.

{
  "level": 30,
  "time": 1720120558325,
  "pid": 18553,
  "hostname": "Anubhavs-MacBook-Air.local",
  "req": {
    "id": "req-1",
    "method": "GET",
    "url": "/",
    "headers": {
      "host": "localhost:3000",
      "connection": "keep-alive",
      // ...headers truncated for brevity
    },
    "remoteAddress": "::1",
    "remotePort": 64853
  },
  "res": {
    "statusCode": 200,
    "headers": {
      "content-type": "text/html; charset=utf-8",
      "content-length": "13",
      // ...headers truncated for brevity
    },
    "responseTime": 1.1204520016908646
  },
  "msg": "request completed"
}

You can even customize these logs to include any additional info you need, like logging user details when specific routes are accessed.

app.get('/user/:id', (req, res) => {
  const userId = req.params.id;
  req.log.info({ userId }, 'User route accessed');
  res.send(`User ID: ${userId}`);
});

Tailoring Pino Logging

Pino’s customization options allow you to mold the logging to fit your needs perfectly.

Log Levels: Adjust the verbosity by setting different log levels. For instance, setting the log level to info for production and debug during development.

const logger = pino({ level: 'info' });

Custom Serializers: Craft your own serializers to format log data precisely as you need it. This is useful for refining how request and response logs are shown.

const httpLogger = pinoHttp({
  logger,
  serializers: {
    req: (req) => ({ method: req.method, url: req.url }),
    res: (res) => ({ statusCode: res.statusCode }),
  },
});

Pretty Printing: If you’re all about readability, integrate pino-pretty for logs that are easy on the eyes.

const pretty = require('pino-pretty');
const logger = pino(pretty());

Performance and Benchmarks

Pino’s high performance is no joke. It’s built to handle high-traffic applications efficiently. Radiating speed and capability, Pino consistently outshines other popular logging libraries.

Here’s a snapshot of how Pino ranks in request rates compared to others:

express-bunyan-logger: 2702 req/sec
express-winston: 5953 req/sec
morgan: 8570 req/sec
pino-http: 9807 req/sec

Conclusion

Bringing Pino into your Express application is not only easy but can turbocharge how you monitor and debug. Pino’s high performance, customizable features, and seamless integration with Express make it a fantastic tool for any Node.js developer looking to up their logging game. With the guide laid out above, you’re set to create a solid logging system that keeps you on top of your application’s heartbeat.

And there you have it – a robust, efficient logging setup, ready to go. Time to code, log, and keep your app running smooth as butter. Cheers!

Keywords: Pino logging, express applications, Node.js logging tools, pino-http setup, high-performance logging, custom serializers, log levels in Node.js, integrating Pino, monitoring Express apps, pino-pretty readability



Similar Posts
Blog Image
Concurrent API Requests in Angular: RxJS Patterns for Performance!

Concurrent API requests in Angular boost performance. RxJS operators like forkJoin, mergeMap, and combineLatest handle multiple calls efficiently. Error handling, rate limiting, and caching improve reliability and speed.

Blog Image
10 Advanced JavaScript Object Techniques Every Developer Should Master in 2024

Master JavaScript object manipulation with expert techniques. Learn destructuring, immutability, merging, and advanced operations for modern web development. Includes practical code examples and performance tips. #JavaScript #WebDev

Blog Image
Angular’s Custom Animation Builders: Create Dynamic User Experiences!

Angular's Custom Animation Builders enable dynamic, programmatic animations that respond to user input and app states. They offer flexibility for complex sequences, chaining, and optimized performance, enhancing user experience in web applications.

Blog Image
Is Your Express App Missing Its Batman? Discover Log4js!

Turning Logs into Gold: Elevate Express Apps with Log4js

Blog Image
Jest and Webpack: Optimizing for Lightning-Fast Test Runs

Jest and Webpack optimize JavaScript testing. Parallelize Jest, mock dependencies, use DllPlugin for Webpack. Organize tests smartly, use cache-loader. Upgrade hardware for large projects. Fast tests improve code quality and developer happiness.

Blog Image
Exploring Node.js Native Modules: Boost Performance with C++ Addons

Native modules in Node.js are C++ extensions that enhance performance and functionality. They enable low-level system access, making them ideal for computationally intensive tasks or hardware interfacing. Creating and integrating these modules can significantly boost Node.js applications.