Wisdom Ekpot A student of Ibom Metropolitan Polytechnic studying computer engineering, Wisdom has been writing JavaScript for two years, focusing on Vue.js, Angular, and Express.js.

Comparing Node.js logging tools

6 min read 1767

Comaring Node.js Logging Tools

Logging is an important concept in software engineering. By writing out an audit of events that occur in an application, logs provide insight to developers when trying to understand what an app’s code actually does.

In this post, we’ll compare different logging tools for Node.js, including:

But before we look at the comparisons, let’s dive into the elements of logging.

Why should we log?

When working with logs in any application, it is important to understand logging levels. A logging level is a way of classifying the entries in a log file in terms of urgency and how to display them.

Each defined log message has an associated log level that gives a rough guide to the importance and urgency of the message. The most common logging levels in Nodejs are:

  • ERROR
  • INFO
  • DEBUG
  • WARN
  • FATAL

Each of these log levels have their own use cases and how to apply them.

ERROR log level

The ERROR level indicates a serious problem that must be dealt with. It designates error events that might still allow the application to continue running.

INFO log level

This log level keeps track of an event that has occurred. These alerts can usually be ignored, assuming the rest of the system continues to operate normally.

It basically indicates informational messages that highlight the progress of the application at a granular level.

DEBUG log level

The DEBUG log level contains information that is only useful during the debug phase and may be of little value during production. They are basically informational events that are most useful when debugging an application.

WARN log level

The WARN log level is slightly less severe than error conditions because they indicate potentially harmful situations. The message indicates that an unexpected event occurred in an application that may disrupt or delay other processes.

FATAL log level

This log level indicates very severe error events that presumably lead the application to abort.



Node.js Logging Libraries

Now that we understand the different log levels, we can dive into the different logging tools in Node.js and how to use them in our application.

Bunyan

Bunyan is a very popular logging tool in Node.js. It is a simple and fast JSON logging library for Node.js services that provides a beautiful logging CLI view describing the different logging levels in different colors.

Bunyan Interface Showing Different Coloring For Code

Installing Bunyan

To install Bunyan, add the following to your terminal:

npm i bunyan

Using Bunyan

To start logging with Bunyan, create a test.js file and add this code for testing purposes:

const bunyan = require('bunyan');

After requiring the package, we must define an instance of the logger using the createLogger method:

var log = bunyan.createLogger({
  name: '<name of application',
  stream: process.stdout
});

We can then use Bunyan to log data:

log.info('hi');

If we run our test.js file, we get this output in the console:

{"name":"myapp","hostname":"banana.local","pid":40161,"level":30,"msg":"hi","time":"2013-01-04T18:46:23.851Z","v":0}

Here it is clear that Bunyan advocates that logs should be in JSON format and each log carries the date when the log was made. A common practice in Node.js is storing these log entities in a file for reference purposes.

Benefits of Bunyan

Bunyan supports multiple runtimes in addition to Node.js like Webpack, Browserify, and NW.js.

Bunyan also has the concept of serialization where functions produce a JSON-able object from a JavaScript object. Here, a particular logger instance can have a serializer that maps a log record field name to a serializer function.

And with child logging, developers can specialize a logger for a subcomponent of an application, like creating a new logger with additional bound fields that are included in its log records.

Winston

Winston is a top Node.js logging library with over 17k stars on GitHub at the time of writing this post due to its large community and functionality.

Winston decouples parts of logging and makes it extensible and flexible with a lot of configuration, making development seamless.

Installing Winston

To install Bunyan, add the following to your terminal:

npm i winston

Using Winston

After installing the library, we must require the library in our root file and create an instance of it:

const winston = require('winston');
const logger = winston.createLogger({})

The createLogger methods can hold a lot of configurations such as the log level, the format, and a meta description:

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  defaultMeta: { service: '<service>' },
});

Also, we can specify a file where all logs are written to by including the file in the transport array:

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  defaultMeta: { service: 'user-service' },
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
  ],
});

Here we are setting all logs with a log level of error must be written into the error.log file while all other logs must be written into the combined.log file.

We can also choose to only display our logs in the console by using this configuration in the transport array:

new winston.transports.Console()

To get all the methods that Winston provides, you can reference the documentation.

Winston benefits

Winston gives the ability to send logs to other cloud logging services such as logz.io and AWS Cloudwatch instead of storing logs in a static file or logging them on the console.

Since each log has a timestamp and a log level, logs can be easily traced based on any occurrences.


More great articles from LogRocket:


Pino

Pino touts itself as a “very low overhead” Node.js logger because it uses minimum resources for logging. With Pino, logged messages are added over time, thus leading to a throttling effect on applications such as reduced requests per second.

Throttling is a methodology where, no matter how many times the user fires the event, the attached function executes only once in a given time interval.

Installing Pino

To install Pino, add the following to your terminal:

npm i pino

Using Pino

Using this library is quite easy and very straightforward. All you have to do is require the library and initialize it:

const logger = require('pino')()

logger.info('hello world')

Running this script produces the following on the console:

{"level":30,"time":1531171074631,"msg":"hello world","pid":657,"hostname":"Davids-MBP-3.fritz.box"}

This logged data on the console consists of the log level, the time the data was logged, the actual message of the log, the id of the log, and the host.

Using the Pino in Express.js

You can also use Pino in your Express.js application by installing this package:

npm install pino-http

After installing this library, you can use it in your Express.js application like so:

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

const app = express();
const pinoInstance = pino()

app.use(pinoInstance);

app.post('/do-stuff', (req,res) => {
  req.log.info('Something done');
  res.send('Say hello to Pino')
})

app.listen(5500)

Pino benefits

Pino has a module that provides a basic NDJSON formatter called pino-pretty.

The Newline Delimited JSON, or NDJSON, is a convenient format for storing or streaming structured data that can process one record at a time. All logged data applies extra formatting by considering things like the log level and timestamp.

You can install pino-pretty on your project or globally on your local machine.

To install pino-pretty, run this command:

npm install -g pino-pretty

After installing, you can run your application using the following command:

node app.js | pino-pretty

Morgan

Morgan is a Node.js library used for logging HTTP requests. It is usually added as a middleware so that it can track all requests made. Unlike other logging tools, its primary function is to log HTTP requests.

Installing Morgan

To install Morgan, add the following to your terminal:

npm i morgan

Using Morgan

After installation, you must require the library and then add it as an Express.js middleware:

var morgan = require('morgan')

app.use(morgan('dev'))

The dev passed is a Morgan format. Morgan implements five logging formats:

  1. combined, which uses the standard Apache combined log output
  2. common, which uses the standard Apache combined log output
  3. dev, which uses concise output colored by the response status for development use
  4. short, which includes response time and shortens the log by default
  5. tiny, which uses a minimal output

You can then use these formats as seen below:

app.use(morgan('combined'))
app.use(morgan('common'))
app.use(morgan('dev'))
app.use(morgan('short'))
app.use(morgan('tiny'))

Morgan benefits

Without having to write extra configuration codes, Morgan gives you the ability to choose any of the predefined formats that were created depending on your niche, saving you time.

npmlog

This is the official logger utility that npm uses. Just like other Node.js logging libraries, it supports custom levels, colored output, and gives you the ability to set different colors for your different log levels.

Installing npmlog

To install Npmlog, add the following to your terminal:

npm i npmlog

Using npmlog

To begin using the library, create a test file and then require the package:

const log = require('npmlog');
log.info('Wisdom Ekpot', 'Hello from logrocket', {'message': 'test'})

The log.info logs data on the console or file and it can accept up to there parameters:

  • First parameter: the prefix of the log
  • Second parameter: the actual log message
  • Third parameter: additional data for the log

npmlog benefits

Just like every other logging tool, npmlog comes with a lot of methods to simplify development such as setting log headers, heading styles, and defining log levels.

Node.js logging libraries’ stats

Below is a quick comparison of the Node.js logging libraries we covered in this article; all data is accurate at the time of posting this article.

Library Number of weekly downloads Github stars Github forks
Bunyan 1,568,274 6.7k 522
Winston 6,364,282 17.8k 1.6k
Pino 1,836,807 7.8k 530
Morgan 2,873,389 6.7k 485
npmlog 13,220,573 358 55

Conclusion

Going through all these Node.js logging tools, it shows that it’s quite simple and straightforward to implement logging in any of our Node.js projects. It is often recommended to use the library that fits your application purpose and displays the actual data needed.

200’s only Monitor failed and slow network requests in production

Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third party services are successful, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. .
Wisdom Ekpot A student of Ibom Metropolitan Polytechnic studying computer engineering, Wisdom has been writing JavaScript for two years, focusing on Vue.js, Angular, and Express.js.

Leave a Reply