Last9 Last9

Jan 16th, ‘25 / 7 min read

pino-pretty: A Guide to Pretty-Printing Your Logs

Learn about pino-pretty and how it can transform raw JSON logs into a readable, human-friendly format for easier debugging.

pino-pretty: A Guide to Pretty-Printing Your Logs

Logs are essential for understanding what’s going on inside your application. However raw JSON logs can be hard to read. pino-pretty is a tool that formats Pino logs into a more readable, color-coded format, making it easier to debug and understand what’s happening in your app.

What is Pino-Pretty?

pino-pretty is an add-on for Pino, a fast logging library for Node.js. Pino normally outputs logs in JSON format, which is great for machines but not very easy for developers to read.

pino-pretty takes those JSON logs and formats them into a more user-friendly format with color coding, making them much easier to work with while debugging.

Why Use Pino-Pretty?

Here’s why you should use pino-pretty:

  • Easier to Read Logs: Raw JSON is tough to read. pino-pretty formats logs in a way that’s easy to follow, making debugging quicker.
  • Fast Performance: pino-pretty is lightweight and doesn’t slow down your application.
  • Customizable Format: You can customize how your logs appear, including adding timestamps, colors, and which data to show.
  • Works with Pino: It integrates well with Pino and other Node.js tools, so you don’t need to worry about compatibility issues.
Check out our guide on how to set up and manage cron jobs in Node.js for more insights on scheduling tasks.

Installation of pino-pretty

Getting started with pino-pretty is simple. It enhances the readability of logs generated by the Pino logger, making them easier to analyze. Here's how you can install it:

1. Prerequisites

Before installing pino-pretty, make sure:

  • Node.js is installed on your system.
  • npm (Node Package Manager) or Yarn is available for package management.

2. Installing pino-pretty

You can install pino-pretty either globally or as a project-specific development dependency.

Global Installation

To install globally and use pino-pretty across multiple projects, run:

npm install -g pino-pretty

Or with Yarn:

yarn global add pino-pretty
For another logging solution in Node.js, take a look at our post on Winston logging in Node.js.

Project-Specific Installation

If you want to install it only for your current project, run:

npm install --save-dev pino-pretty

Or with Yarn:

yarn add --dev pino-pretty

3. Verification

After installation, verify that Pino-Pretty is installed correctly by running:

pino-pretty --version

This command will show the version number of the installed package.

4. Integration with Pino

To use Pino-Pretty, pipe the output of your Pino logger through it. For example:

node app.js | pino-pretty

Alternatively, configure Pino to use Pino-Pretty programmatically:

const pino = require('pino');
const pretty = require('pino-pretty');
const logger = pino(pretty());
logger.info('Hello, Pino-pretty!');

Once you've followed these steps, you're all set to make your logs more readable and debugging easier!

Configuring pino-pretty

You can configure pino-pretty either through the CLI or programmatically.

CLI Configuration

To pipe your Pino logs through Pino-Pretty from the command line:

node app.js | pino-pretty

You can also customize the output using CLI options:

node app.js | pino-pretty --colorize --levelFirst --translateTime "HH:MM:ss"

Here’s what these options do:

  • --colorize: Adds color to log levels.
  • --levelFirst: Displays the log level before the message.
  • --translateTime: Formats the timestamp for better readability.
To understand how syslog works in Linux, check out our detailed guide on Linux Syslog Explained.

Programmatic Configuration

Alternatively, configure pino-pretty directly in your code:

const pino = require('pino');
const logger = pino({
  transport: {
    target: 'pino-pretty',
    options: {
      colorize: true,
      levelFirst: true,
      translateTime: 'HH:MM:ss',
    },
  },
});
logger.info('Hello, pretty logs!');

Color Support in Terminal Outputs

When using pino-pretty, color output can improve the readability of logs, but not all terminal environments support colors. Here's how you can manage color output effectively:

1. Checking Color Support

pino-pretty uses libraries like chalk or colorette to handle colors in terminal outputs. These libraries automatically detect if the terminal supports color. You can verify this programmatically using the supports-color package.

Example:

const supportsColor = require('supports-color');
if (supportsColor.stdout) {
  console.log('Your terminal supports color!');
} else {
  console.log('No color support detected.');
}

2. Enabling or Disabling Colors

You can control color usage with the --colorize option. Here’s how to enable or disable colors:

  • Enable Colors: Use --colorize when running the command:
pino-pretty --colorize
  • Disable Colors: Skip the option or explicitly turn it off:
pino-pretty --colorize=false
For more on managing and viewing system logs with systemctl, take a look at our blog on Systemctl Logs Explained.

3. Fallback for Non-Supporting Environments

For environments that don’t support colors, such as certain CI/CD pipelines, ensure your logs remain readable without relying on color. Use clear text markers or structured JSON to maintain clarity:

Example:

console.log('INFO: Application started');

Customizing pino-pretty

pino-pretty provides various customization options to make your logs even more suited to your needs:

1. Color Schemes

Choose different colors for various log levels (info, error, debug, etc.) to make logs more visually distinct.

2. Timestamps

Customize the format of your timestamps for easy parsing and alignment with your needs.

3. Keys

Select which keys to include or exclude from the log output, making the logs cleaner and more relevant to your use case.

For a complete list of customization options, refer to the documentation.

Best Practices for Using pino-pretty

1. Use in Development

pino-pretty is ideal for local debugging but should be avoided in production. In production, stick to raw JSON logs for better machine parsing and performance.

2. Pair with Log Aggregators

Tools like Elasticsearch or Loki can ingest Pino's raw JSON logs. Use pino-pretty locally for debugging, but let the aggregation tools handle log parsing in production.

3. Test Your Config

Before rolling out changes, always test your pino-pretty configuration to ensure the output meets your expectations and is easy to read.

Learn how to simplify your log parsing with the Grok Debugger in our latest post.

Limitations of pino-pretty

1. Not Suitable for Production

pino-pretty is designed for development use, not production. Its formatting can slow down performance due to the extra processing, so it's best to stick with raw JSON logs in production for better efficiency.

2. Limited Formatting Options

While pino-pretty offers basic log formatting, it’s not a full-featured solution. You won’t find advanced customization options like custom parsing or highly complex styling.

3. Increased Resource Usage

Prettifying logs takes extra computing power, which can affect performance—especially in high-logging environments. This usually isn’t an issue during development but can be a concern in resource-limited situations.

4. Terminal-Dependent Features

Some features like colored output rely on terminal support for ANSI codes. In environments without proper support (like certain CI/CD systems or older terminals), logs might appear plain or not formatted as expected.

5. Potential Log Misinterpretation

Prettified logs, while more human-readable, might be hard for other tools to parse. If you need to process logs programmatically, this format could cause issues and require additional handling.

6. Limited Logging Ecosystem Integration

pino-pretty works best as a standalone tool. If you're using external logging systems (like Elasticsearch or Loki), you’ll need an extra setup to forward your logs in a structured format.

Check out our post on Morgan NPM and its role in Node.js to learn more about log handling in Node.js.

Handling Non-Serializable Options in pino-pretty

When working with pino-pretty, you might encounter scenarios where non-serializable options (e.g., functions, circular references, or unsupported types) are part of the data being logged.

Since pino-pretty primarily processes JSON-compatible data, handling these non-serializable options effectively ensures that your logs remain meaningful and error-free.

1. Understanding the Issue

pino-pretty is built to prettify structured JSON logs. However, non-serializable data—like objects with circular references or custom functions—cannot be converted to JSON. Attempting to log such data can lead to errors, truncated output, or missing information.

Example of problematic data:

const circularObj = {}; 
circularObj.self = circularObj; 
const logger = require('pino')(); 
logger.info(circularObj); // Results in an error or incomplete output.

2. Strategies to Handle Non-Serializable Data

a) Filter or Transform Data Before Logging

You can preprocess your data to remove or replace non-serializable elements before passing it to the logger.

Example:

const safeLog = (data) => { 
  try { 
    return JSON.stringify(data); 
  } catch (error) { 
    return '[Non-serializable data]'; 
  } 
}; 

const logger = require('pino')(); 
logger.info(safeLog({ key: 'value', circular: circularObj }));

b) Use Custom Serializers

Pino allows custom serializers to handle specific fields or object types. This is particularly useful for logging complex objects or stripping out non-serializable elements.

Example:

const pino = require('pino'); 
const logger = pino({ 
  serializers: { 
    custom: (value) => { 
      if (typeof value === 'function') { 
        return '[Function]'; 
      } 
      return value; 
    }, 
  }, 
}); 
logger.info({ custom: () => {} }); // Outputs: { custom: '[Function]' }

c) Stringify Non-Serializable Data

You can manually stringify objects with circular references using libraries like util.inspect or flatted to ensure compatibility.

Example:

const util = require('util'); 
const logger = require('pino')(); 
const circularObj = {}; 
circularObj.self = circularObj; 
logger.info(util.inspect(circularObj, { depth: null }));

d) Log Only Serializable Data

For environments where only serializable data is required, validate your logs upfront and skip logging any problematic data.

3. Best Practices

  • Keep Logs Simple: Use plain objects and primitives wherever possible.
  • Validate Data: Check for non-serializable elements before logging, especially in user-generated data or third-party API responses.
  • Document Log Structures: Define and enforce consistent logging formats in your application to reduce unexpected issues.
For another logging solution, take a look at our guide on logging errors in Go with Zerolog.

Common Issues and Troubleshooting

  • Missing Logs: If logs aren't showing up, check your transport configuration and make sure everything is correctly set up.
  • Performance Concerns: Ensure Pino-Pretty is only used in development to avoid unnecessary overhead in production environments.
  • Version Mismatch: Verify that the versions of Pino and Pino-Pretty you’re using are compatible to prevent any integration issues.

License for pino-Pretty

Key Terms of the MIT License

  • Use, Modify, and Share: You can freely use, copy, modify, and even sell the software. You can also share it with others, as long as you include the original copyright and permission notice.
  • No Warranty: The software comes "as is." This means the authors aren’t responsible for any issues or problems that arise from using it.

Why It Matters

The MIT License makes pino-pretty free to use in both personal and commercial projects. It encourages sharing and collaboration, so you can modify and redistribute the software under the same terms.

Where to Find It

The full MIT License text is in the LICENSE file in the pino-pretty GitHub repo, and it’s also included in the package documentation.

Wrapping Up

Pino-Pretty takes the grunt work out of reading logs. Whether you’re troubleshooting a bug or just want your logs to look as good as your code, Pino-Pretty is a must-have.

Logs don’t have to be a pain to read. With Pino-Pretty, they’re clear, colorful, and—dare we say it—pretty. Happy logging!

If you have any more questions or want to continue the conversation, feel free to join our Discord community! We have a dedicated channel where you can connect with other developers and discuss your use case.

Contents


Newsletter

Stay updated on the latest from Last9.

Authors
Preeti Dewani

Preeti Dewani

Technical Product Manager at Last9

X
Topics