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 pinonpm i -D pino-pretty# Optional : Use the Elastic Common Formatnpm i @elastic/ecs-pino-format
And use it like this :
import { logger } from "logger";
// Simplest examplelogger.info("Yay");
// Add more contextconst ctx = { user: "foo", action: "delete", reason: "whatever" };logger.debug(ctx, "User deleted");