A simple yet production ready NodeJS logger

July 27, 2020

Here is my go-to snippet for a consistent, production-ready logger in NodeJS or Typescript :

logger.js

import pino from "pino";
import ecsFormat from "@elastic/ecs-pino-format"; // Optional

export const logger = pino({
  ...ecsFormat(), // Optional
  level: process.env.LOG_LEVEL || "info",
  prettyPrint:
    process.env.NODE_ENV !== "production" ||
    process.env.LOG_PRETTY_PRINT === "true",
});

What's inside ?

  • JSON logging: It logs everything in a JSON format. Having JSON logs is extremely useful when you want to parse them with e.g. Papertrail or any other log-management service.
  • Debug Context: It supports adding context objects with your message (yeah, Pino is really awesome).
  • Great Developer Experience: When running on your local machine, it will display colored, well-spaced logs for a better developer experience, thanks to pino-pretty.
  • Default log level: Using default level "info" avoid spamming a new environment with tons of logs if you forget to set the variable.
  • Nice trick: The LOG_PRETTY_PRINT variable allows us to enable pretty-printing even in production environement. Useful for quick debugging tasks.
  • Optional - ECS format: I often use Elastic Common Schema as a logging format. It comes with great defaults, and is of course ideal if you are sending your logs to an ELK stack.

That's it! It just works :)

Usage

Add its dependencies to your project :

npm i pino
npm i -D pino-pretty
# Optional : Use the Elastic Common Format
npm i @elastic/ecs-pino-format

And use it like this :

import { logger } from "logger";

// Simplest example
logger.info("Yay");

// Add more context
const ctx = { user: "foo", action: "delete", reason: "whatever" };
logger.debug(ctx, "User deleted");