The Top 4 Packages for Logging in Node.js

Proper logging is a critical aspect of building and maintaining functional web applications. It can help you track errors, diagnose performance problems, and understand how users interact with your app.

Node.js has many logging packages to help you create and manage structured logs. Here you will explore the top logging packages currently available in the Node.js ecosystem and how to use them.

1. Winston

winston github summary

Winston is a Node.js library that provides flexible logging functionality, including multiple transports. A “transport” is a storage medium for your logs.

Winston supports console, file, and network transports. This means you can print your logs to the console, write them to a file, or send them over a network. Using Winston’s logging levels, you can create custom transports and filter logs based on severity.

You can install Winston as a dependency in your project directory using npm, the JavaScript package manager. Run this command:

 npm install winston

The code block below demonstrates how to set up a basic logging system using Winston. You can define logs for different locations and varying levels of severity.

 

const

winston =

require

(

"winston"

);


const

logger = winston.createLogger({
  level:

'info'

,
  format: winston.format.json(),
  defaultMeta: {

service

:

'my-service'

},
  transports: [
    

new

winston.transports.Console(),
    

new

winston.transports.File({

filename

:

'error.log'

,

level

:

'error'

}),
    

new

winston.transports.File({

filename

:

'combined.log'

})
  ]
});

logger.info(

'Hello, Winston!'

);
logger.warn(

'Warning: Something may be wrong.'

);
logger.error(

'An error occurred.'

);

This code configures a logger with three transports. The first is a console transport, which will output log messages to the console. The second is a file transport that will write logs with a level of “error” to an “error.log” file. The third is a file transport that will write all logs to a “combined.log” file.

The logger is set to log at the “info” level by default and includes a default metadata object with a “service” field set to “my-service”.

The code then logs three messages using the logger at the “info”, “warn”, and “error” levels, respectively. These messages will be output to the console and the appropriate log files according to the configuration of the transports.

2. Morgan

Morgan.js github summary

Morgan is a logging middleware for Node.js that provides basic request-logging capabilities. It is designed to be lightweight and easy to use. Morgan works by intercepting HTTP requests and logging relevant information, such as the request method, URL, status code, etc.

One of the key benefits of Morgan is its simplicity. You can add it to a Node.js application with a few lines of code, as it requires no additional configuration to set up.

Morgan supports multiple logging formats, including the common, combined, short, tiny, and dev formats, allowing you to choose one that best suits your needs.

You can install Morgan as a dependency in your project directory by running this command:

 npm install morgan

This code shows how to use Morgan in an Express application:

 

const

express =

require

(

"express"

);

const

morgan =

require

(

"morgan"

);

const

app = express();

app.use(morgan(

"dev"

));

app.get(

"/"

, (req, res) => {
  res.send(

"Hello World!"

);
});

app.listen(

3000

, () =>

console

.log(

`App Started`

));

The code initializes Morgan using the dev format. When you make a GET request to the root route (/), Morgan logs the details of that request to the console.

Despite its simplicity, Morgan is a powerful logging package that provides essential request-logging capabilities for Node.js applications.

3. Pino

Pino.js GitHub Summary

Pino is a popular and lightweight logging package for Node.js applications that boasts fast performance and low overhead, as stated in their benchmarks.

Pino supports multiple transport types, easily extended with custom transports. One of Pino’s key features is its ability to log JSON-formatted messages, which makes them easy to parse and analyze.

The use of Pino varies depending on the Node.js framework; you can install Pino as a dependency in your Express project directory by running the command below:

 npm install pino-http

For different frameworks, check the Pino documentation.

This code block shows Pino’s usage in an Express application:

 

const

express =

require

(

"express"

);

const

app = express();

const

pino =

require

(

'pino-http'

)()

app.use(pino)

app.get(

"/"

, (req, res) => {
  pino(req, res)
  req.log.info(

'root route'

)
  res.send(

"Hello World!"

);
});

app.listen(

3000

, () =>

console

.log(

`App Started`

));

This code initializes Pino and registers it as middleware. When you make a GET request to the root route (/), Pino logs the details of your request and its response to the console.

4. Debug

Debug.js GitHub summary

Debug is a logging package for Node.js modeled after Node.js core’s debugging technique. It provides a lightweight logging solution that allows you to enable or disable logging selectively without modifying the code, making it easy to debug and troubleshoot issues.

Debug also allows you to set log namespaces, which provide a hierarchical structure to your logs based on the components and modules in your application, making it easier to filter and search them. Additionally, Debug offers various logging levels, such as error, warn, and info, which you can use to prioritize and filter their logs.

You can install Debug as a dependency in your project directory with this command:

 npm install debug

This code shows Debug’s usage in an Express application:

 

const

express =

require

(

'express'

);


const

debug =

require

(

'debug'

)(

'myapp:server'

);

const

app = express();

const

port = process.env.PORT ||

3000

;

app.get(

'/'

, (req, res) => {
  debug(

'Received request for /'

);
  res.send(

'Hello, world!'

);
});

app.listen(port, () => {
  debug(

`Server listening on port

${port}

`);
});

The code creates a namespace, myapp:server. This namespace will distinguish logs related to your “server” module from those associated with other modules with a different namespace in your application.

Run this command to start up debug:

 DEBUG=myapp:* node server.js

This command above will match any log message with a namespace that starts with myapp:. If you only want to see logs related to your server module, you can set the DEBUG environment variable to myapp:server.

Another advantage of Debug is its compatibility with other logging packages, such as Winston.

Choosing a Logging Package

Choosing a logging package is an important decision that can significantly impact the efficiency and effectiveness of your debugging process. It’s essential to consider factors such as the features and capabilities of the package, its compatibility with your programming language and development environment, and its ease of use and configuration.

Ultimately, the choice of logging package will depend on your project’s specific needs and requirements.