Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk15 min

How to Implement Logging in a Node.js Application With Pino Logger

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fast, structured logging is one of the simplest ways to make a Node.js application easier to debug, monitor, and operate in production. Instead of relying on scattered console.log statements, a proper logger captures consistent event data, severity levels, errors, request details, and runtime context in a format that can be searched and analyzed.

Pino is a popular logging library for Node.js because it is designed for high performance while producing JSON logs that work well with modern observability tools. It can handle application logs, HTTP request logs, error serialization, custom fields, and production transports without adding unnecessary overhead to your app.

As an Amazon Associate I earn from qualifying purchases.

This guide walks through implementing Pino from a basic setup to a production-ready configuration, including log levels, structured messages, exception handling, request logging with pino-http, formatting options, transports, and practical logging patterns for real-world Node.js services.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why Use Pino for Node.js Logging

Pino is a popular logging library for Node.js because it is designed around two practical goals: keep application overhead low and produce logs that machines can process easily. In production systems, logging should not become a bottleneck, especially for APIs handling many concurrent requests. Pino writes logs as newline-delimited JSON by default, which makes each log entry structured, compact, and ready for ingestion by platforms such as Datadog, Elastic Stack, Grafana Loki, Better Stack, CloudWatch, or Google Cloud Logging.

#1 Best Overall
HP OmniBook 3 17.3 inch Laptop PC, FHD Display, AMD Ryzen 3 30, 8 GB RAM, 512 GB SSD, AMD Radeon 610M Graphics, Windows 11 Home, Mica Silver, 17-dp0199nr
  • FULL HD IPS DISPLAY - Enjoy vibrant, crystal-clear images with 178-degree wide-viewing angles
  • AMD RYZEN 3 30 PROCESSOR - Everyday performance you can count on; Multitask, stream, game casually, and edit photos smoothly with responsive power and vibrant HDR visuals
  • ENJOY UP TO 14 HOURS AND 15 MINUTES OF BATTERY LIFE - HP Fast Charge restores battery from 0 to 50% in approximately 45 minutes
  • AMD RADEON 610M GRAPHICS - Experience smooth entertainment; Built for streaming and multitasking, enjoy realistic visuals and efficient performance for work and play
  • STORAGE AND MEMORY - 512 GB PCIe NVMe M.2 SSD offers fast speed and efficient storage; and 8 GB LPDDR5 RAM memory boosts performance with higher bandwidth

Compared with plain console.log, Pino gives you consistent fields, severity levels, timestamps, serializers, child loggers, and transport support. This matters when you need to answer operational questions such as which user request failed, which service instance produced an error, or how long a specific endpoint took to respond. Instead of searching through inconsistent text messages, you can filter logs by fields such as level, requestId, userId, route, statusCode, or err.type.

Benefits of using Pino

  • High performance: Pino minimizes synchronous work in the application thread and is optimized for high-throughput Node.js services.
  • Structured JSON output: Logs are emitted as JSON objects, making them easier to query, parse, index, and correlate.
  • Standard log levels: Built-in levels such as trace, debug, info, warn, error, and fatal help control verbosity across environments.
  • Good production defaults: Pino is intentionally minimal in the hot path, with formatting and shipping handled separately through transports or external log processors.
  • HTTP integration: The pino-http package can automatically log incoming requests, responses, latency, status codes, and request-specific context.

Pino’s structured approach also improves observability. A log event can carry business and technical context in the same record: the message, the request identifier, the authenticated account, the database operation, the response status, and the error object. When logs follow a predictable schema, they become more useful alongside metrics and traces. For example, if an alert shows a spike in HTTP 500 responses, you can query logs for level:error and statusCode:500, group by route, and inspect the related stack traces.

Another advantage is that Pino separates human-friendly formatting from production logging. During local development, you can pipe logs through pino-pretty to get readable colored output. In production, you usually keep the raw JSON and let your container runtime, process manager, or observability agent collect stdout. This avoids unnecessary formatting cost in the application and keeps logs compatible with modern deployment environments such as Docker, Kubernetes, serverless functions, and managed Node.js platforms.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Installing and Configuring Pino

Start by adding Pino to your Node.js project with your package manager of choice. Pino works well in plain Node.js services, Express applications, Fastify applications, background workers, and CLI tools because it writes structured JSON logs with very little runtime overhead.

npm install pino

For a minimal setup, create a logger module and export a configured Pino instance. Keeping this in one place makes it easier to apply consistent log levels, redaction rules, serializers, and environment-specific behavior across the application.

const pino = require('pino');

const logger = pino({
level: process.env.LOG_LEVEL || 'info',
base: {
service: 'user-api',
environment: process.env.NODE_ENV || 'development'
},
timestamp: pino.stdTimeFunctions.isoTime
});

module.exports = logger;

You can then import the logger anywhere in your application and write logs as structured events. Instead of building long strings, pass an object with fields that help you search, filter, and correlate logs later.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

const logger = require('./logger');

logger.info({ userId: 'usr_123', action: 'profile_viewed' }, 'User viewed profile');

Choosing an initial configuration

A practical Pino configuration usually starts with a log level, service metadata, timestamp format, and optional redaction. The level controls which messages are emitted. In development, debug can be useful, while production services commonly use info or warn depending on traffic volume and observability requirements.

  • level: Sets the minimum log severity, such as debug, info, warn, or error.
  • base: Adds common fields like service name, runtime environment, region, or version to every log entry.
  • timestamp: Uses a consistent time format, such as ISO 8601, for easier reading and querying.
  • redact: Removes or masks sensitive fields before logs are written.

const pino = require('pino');

const logger = pino({
level: process.env.LOG_LEVEL || 'info',
base: {
service: process.env.SERVICE_NAME || 'node-service',
environment: process.env.NODE_ENV || 'development',
version: process.env.APP_VERSION || 'local'
},
timestamp: pino.stdTimeFunctions.isoTime,
redact: {
paths: [
'password',
'token',
'authorization',
'headers.authorization',
'user.ssn'
],
censor: '[REDACTED]'
}
});

module.exports = logger;

Development-friendly output

By default, Pino writes newline-delimited JSON, which is ideal for production log collectors but not always comfortable during local development. Install pino-pretty as a development dependency if you want readable console output while building and debugging locally.

Rank #2
HP 14" HD Chromebook Laptop for Students, Intel Quad-Core N4120(> N4020), 4GB RAM, 64GB eMMC, WiFi, Webcam, HDMI, USB-A&C, 14 Hours Battery Life, Zoom, Chrome OS, CUE Accessories
  • Intel Celeron N4120: 4 Cores & Threads, 1.1GHz Base Clock, Up to 2.6GHz Boost Clock, 4MB Cache, Intel UHD Graphics 600. The perfect combination of performance, power consumption, and value helps your device handle multitasking smoothly and reliably with four processing cores to divide up the work.

npm install --save-dev pino-pretty

You can enable pretty output only outside production by configuring a transport conditionally. This keeps production logs machine-readable while giving developers a friendlier format on their laptops.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

const pino = require('pino');

const isProduction = process.env.NODE_ENV === 'production';

const logger = pino({
level: process.env.LOG_LEVEL || 'info',
base: {
service: 'user-api',
environment: process.env.NODE_ENV || 'development'
},
timestamp: pino.stdTimeFunctions.isoTime,
transport: isProduction
? undefined
: {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'SYS:standard',
ignore: 'pid,hostname'
}
}
});

module.exports = logger;

Using child loggers for context

Child loggers let you attach persistent fields to a logger instance without repeating them on every call. This is useful for modules, jobs, tenants, request IDs, or integrations. The child logger inherits the parent configuration and automatically includes the additional fields in each log record.

const logger = require('./logger');

const billingLogger = logger.child({ module: 'billing' });

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

billingLogger.info({ invoiceId: 'inv_456' }, 'Invoice generated');

With this setup in place, the application has a single logging entry point, consistent metadata, configurable verbosity, sensitive-field redaction, and readable local output. Later sections can build on this foundation for structured log levels, error logging, HTTP request logs, and production transports.

Writing Structured Logs with Log Levels

Pino writes logs as structured JSON by default, which makes each log entry easy for machines to parse, filter, search, and aggregate. Instead of building long string messages such as “User 42 failed checkout because card expired”, attach fields to the log event and keep the message short. This gives tools like Datadog, Elastic Stack, Loki, Better Stack, or CloudWatch clear attributes to index, such as userId, orderId, paymentProvider, and statusCode.

A typical structured log call passes an object as the first argument and a human-readable message as the second argument. For example, you might log a successful checkout with fields for the user, order, total, and currency. In code, that pattern looks like calling logger.info({ userId, orderId, total, currency }, ‘Checkout completed’). The resulting JSON includes Pino’s standard fields, such as level, time, pid, hostname, and msg, plus the custom fields you supplied.

Log levels help separate routine application activity from events that need investigation. Pino uses numeric levels internally for performance, while exposing familiar methods such as trace, debug, info, warn, error, and fatal. Set the active level when creating the logger so the application only emits entries at that level or above. For local development, debug is often useful. In production, info is a common default because it records normal business events without overwhelming storage with low-level diagnostic details.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Level Use it for Example event
trace Very detailed execution flow Entering a low-level parser or helper function
debug Development diagnostics Feature flag values or cache lookup results
info Normal application events User registered, payment completed, job started
warn Unexpected but recoverable conditions Retrying a failed API call or using fallback data
error Failed operations that need attention Database write failed or payment provider rejected a request
fatal Process-level failures Application cannot start because required configuration is missing

You can configure the level from an environment variable so each environment controls verbosity without changing application code. For example, initialize Pino with a level value from process.env.LOG_LEVEL and fall back to info. This allows a staging environment to run at debug while production stays at info, and it lets operators temporarily increase detail during an incident.

Rank #3
Sale
AKCHART 15.6'' AI Laptop with Office 365 12GB RAM 256GB SSD Win 11 Laptops | 7000mAh Battery, IPS FHD, 180°Viewing, Quad-Core Processor, Type-C, WiFi5, Portable Thin Business Student Laptops, Light Gray
  • Stunning 15.6" FHD IPS Display: Experience crisp 1920x1080 resolution on this 15.6 inch laptop with an IPS panel that delivers wide viewing angles and vivid colors. The narrow-bezel design maximizes screen real estate for comfortable viewing on this Win 11 laptop, whether you're studying or working.
  • Celeron J4105 Processor & 256GB SSD: Powered by a reliable Celeron J4105 processor paired with 12GB DDR4 memory and a fast 256GB M.2 SSD. This laptop computer supports SSD expansion up to 2TB and TF card expansion up to 1TB, so your storage grows with your needs. Delivers smooth multitasking for daily productivity.
  • AI-Powered Win 11 Laptop: Built-in AI features enhance your productivity with smart assistance for writing, summarizing, and task management. Pre-installed with Win 11 and includes Office 365 subscription. This student laptop is backed by 1-year warranty and 24/7 customer support.
  • All-Day 7000mAh Battery & 180° Hinge: The high-capacity 7000mAh battery keeps this laptop powered through long classes or meetings. The 180-degree lay-flat hinge lets you share your screen effortlessly during presentations. This durable laptop computer adapts to your dynamic workflow.
  • Versatile Connectivity Hub: Equipped with USB 3.2, Type-C, Mini HDMI, and 3.5mm audio jack to connect all your peripherals. Stay online anywhere with high-speed 5G WiFi and Bluetooth 4.2. This college laptop keeps you connected at home, in the library, or on the go.

For consistent observability, define a small set of field names and reuse them everywhere. Prefer userId, requestId, traceId, spanId, service, environment, and operation over inconsistent names like uid, req_id, or transaction. Avoid logging secrets, access tokens, passwords, session cookies, full credit card numbers, or raw authorization headers. Structured logs are most valuable when they are predictable, searchable, and safe to retain.

Logging Errors and Exceptions

Error logging is where structured logging becomes especially useful. Instead of writing only a message like “database failed”, log the actual Error object along with context such as the user ID, request ID, operation name, input identifiers, or external service being called. Pino has built-in support for serializing JavaScript errors, so stack traces, error messages, and error types can be captured in a machine-readable format.

A common pattern is to pass an object as the first argument and a human-readable message as the second argument. When logging an exception, place the error under the err property so Pino’s standard error serializer can format it properly:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

try {
await createInvoice(orderId);
} catch (err) {
logger.error(
{ err, orderId, operation: 'createInvoice' },
'Failed to create invoice'
);
}

This produces a structured log entry that includes fields such as level, time, msg, orderId, and operation, plus serialized error details like type, message, and stack. In production, this makes it much easier to search for all failures related to a specific operation, correlate failures with a single request, or group errors by stack trace in an observability platform.

Choosing the right level for errors

Not every exception should be logged at the same severity. Use error for failures that prevent an operation from completing, such as a failed payment authorization, an unavailable database, or an unexpected exception in a route handler. Use warn for recoverable problems, such as a retryable timeout, invalid user input that was handled, or a missing optional integration response. Reserve fatal for errors that require the process to shut down or restart.

  • warn: Recoverable issue, degraded behavior, or expected failure path.
  • error: Operation failed and needs investigation or monitoring.
  • fatal: Process-level failure where the application cannot safely continue.

You should also handle process-level exceptions so unexpected crashes are logged before the application exits. In Node.js, uncaughtException and unhandledRejection are last-resort handlers, not normal control flow. After logging a fatal error, the safest approach is usually to terminate the process and let a process manager such as systemd, PM2, Docker, Kubernetes, or a platform supervisor restart it.

process.on('uncaughtException', (err) => {
logger.fatal({ err }, 'Uncaught exception');
process.exit(1);
});

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

process.on('unhandledRejection', (reason) => {
logger.fatal({ err: reason }, 'Unhandled promise rejection');
process.exit(1);
});

For application-specific errors, include stable fields that help with filtering and alerting. For example, add code, statusCode, requestId, or service when available. Avoid logging secrets, access tokens, passwords, full credit card numbers, or sensitive personal data inside error context. Good error logs should make failures diagnosable without exposing data that does not belong in logs.

Adding HTTP Request Logging with Pino HTTP

Application logs become much more useful when they can be tied to incoming HTTP traffic. pino-http is the official middleware-style package for adding request and response logging to Node.js servers. It records structured details such as the HTTP method, URL, status code, response time, remote address, and user agent, while reusing the same Pino logging model used elsewhere in the application.

Install it alongside Pino if it is not already available in your project:

Rank #4
Sale
HP Essential Laptop 2026, Intel CPU, 128GB Storage, Office 365, Windows 11 | Copilot AI, WiFi 6, Long Battery Life, Lightweight & Portable, Online Learning, Browsing, Streaming, Willow Green
  • Efficient Performance for Everyday Computing: Powered by Intel N150 processor with up to 3.6 GHz Intel Turbo Boost Technology, 6 MB L3 cache, 4 cores, and 4 threads, this HP laptop delivers responsive performance for web browsing, streaming, document editing, and multitasking. Paired with 4GB LPDDR5 RAM and 128GB UFS storage, it handles daily tasks smoothly. Includes 1-year Microsoft 365 Personal subscription for Word, Excel, PowerPoint, and cloud storage to maximize your productivity.
  • 14-Inch HD Micro-Edge Display:Enjoy clear visuals on the 14-inch HD (1366 x 768) anti-glare screen with 250-nit brightness and 62.5% sRGB coverage. The micro-edge bezel delivers a 79% screen-to-body ratio in a compact design. An HP True Vision 720p HD camera with noise reduction and dual-array microphones supports clear video calls, remote work, and online learning.
  • Modern Connectivity and Wireless Technology: Stay connected with Wi-Fi 6 (2x2) for faster wireless speeds and Bluetooth 5.4 for seamless pairing with accessories. Versatile port selection includes 1 USB Type-C 10Gbps with DisplayPort 1.2 for external displays, 2 USB Type-A 5Gbps ports for peripherals, 1 HDMI 1.4b port, 1 headphone/microphone combo jack, and 1 multi-format SD media card reader. Connect monitors, transfer files quickly, and expand your workspace with ease.
  • All-Day Battery Life and Portable Design: Enjoy up to 11 hours of video playback, 7.5 hours of mixed usage, or 7.5 hours of wireless streaming on a single charge, perfect for students and professionals on the go. Weighing just 3.24 lb and measuring 12.76" x 8.86" x 0.71", this lightweight laptop fits easily in backpacks and bags. The stylish willow green top cover with matte finish and natural silver keyboard deck with vertical brushing pattern offer a modern, professional look.
  • AI-Enhanced Productivity: Access Microsoft Copilot instantly with the dedicated Copilot key for faster assistance. AI Noise Reduction filters background sounds and improves voice clarity during calls. Dual speakers provide clear audio, while the full-size natural silver keyboard and HP Imagepad support comfortable typing and navigation.

npm install pino pino-http

In an Express application, create a logger and register pino-http before your routes so every request receives a child logger on req.log:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

const app = express();

const logger = pino({
level: process.env.LOG_LEVEL || 'info'
});

app.use(pinoHttp({ logger }));

app.get('/users/:id', async (req, res, next) => {
try {
req.log.info({ userId: req.params.id }, 'Fetching user');
res.json({ id: req.params.id });
} catch (err) {
req.log.error({ err }, 'Failed to fetch user');
next(err);
}
});

app.listen(3000, () => {
logger.info('Server listening on port 3000');
});

With this setup, Pino emits one log entry when the request completes, including response metadata and elapsed time. Any logs written with req.log inside route handlers include the request context, making it easier to follow everything that happened during a single request. This is especially useful when debugging slow endpoints, failed API calls, or unexpected status codes in production.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Customizing request logs

pino-http supports practical customization for real applications. You can rename fields, attach request IDs, redact sensitive values, and change log levels based on the response status code. A common production setup adds a correlation ID so logs from gateways, services, and background jobs can be linked together.

const crypto = require('crypto');

app.use(pinoHttp({
logger,
genReqId: (req) => req.headers['x-request-id'] || crypto.randomUUID(),
customLogLevel: (req, res, err) => {
if (err || res.statusCode >= 500) return 'error';
if (res.statusCode >= 400) return 'warn';
return 'info';
},
customProps: (req) => ({
requestId: req.id,
userId: req.user?.id
}),
redact: {
paths: [
'req.headers.authorization',
'req.headers.cookie',
'req.body.password'
],
censor: '[REDACTED]'
}
}));

The generated request ID is available as req.id and is included in the automatic request log. If a client already sends an x-request-id header, preserving it allows traces to continue across mulle services. Redaction prevents secrets such as bearer tokens, cookies, and passwords from being written to logs, which is essential for safe observability.

Using request logs effectively

  • Register middleware early: add pino-http before route handlers so all downstream logs can use req.log.
  • Log business context: include stable identifiers such as userId, orderId, or tenantId, not full objects or sensitive payloads.
  • Use status-based levels: treat 5xx responses as error, 4xx responses as warn, and successful requests as info.
  • Keep logs structured: prefer fields like { orderId, durationMs } over long interpolated strings.

For services built on Fastify, request logging is already powered by Pino, so you typically configure it through Fastify’s built-in logger option rather than adding pino-http. For Express, Koa, native HTTP servers, and similar frameworks, pino-http provides the same structured request-level visibility with minimal overhead.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Formatting, Transports, and Production Best Practices

Pino writes newline-delimited JSON by default, which is the right format for production because it is fast to generate, easy to parse, and friendly to log pipelines such as Fluent Bit, Vector, Logstash, Datadog, New Relic, CloudWatch, and Google Cloud Logging. Each log line should remain a single JSON object with consistent fields such as level, time, pid, hostname, msg, request identifiers, user or tenant identifiers where safe, and application context. Avoid turning production logs into pretty text, because colorized multi-line output is harder for machines to ingest and query.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For local development, use a transport such as pino-pretty to make logs easier to read without changing the production format. A common setup is to enable pretty output only when NODE_ENV is not production. This keeps developer ergonomics high while preserving structured logs in deployed environments. For example, development logs might show readable timestamps and colored levels, while production logs should remain compact JSON written to stdout and stderr, allowing the runtime platform to collect and route them.

Best Value
HP 14'' Laptop, Intel N150 CPU, 4GB RAM, 128GB SSD, Long Battery Life, 1TB Cloud Storage, Win 11 with Microsoft 365
  • 【Expansive Display】The 14 Non-touch display offers clear, and anti-glare coating, perfect for both work and entertainment.
  • Designed for mobility with a slim 0.71-inch profile and lightweight, making it easy to carry between home, office
  • 【Versatile Connectivity】 connected with multiple ports including USB 3.0 Type-C, and a headphone/mic combo jack, with Wi-Fi and Bluetooth for seamless wireless networking.
  • One Year Microsoft 365

Using transports safely

Pino transports let you send logs through a processing target, such as a pretty printer, file writer, or external log service adapter. In modern Pino versions, transports run outside the main application flow so that formatting and delivery work does not slow down request handling. Still, treat transports as part of your reliability design: if a remote logging endpoint becomes slow or unavailable, your application should not block every request while trying to ship logs. In containerized deployments, the simplest and most robust pattern is usually to write JSON logs to standard output and let the platform handle forwarding.

  • Development: use pino-pretty for readable console output, expanded error stacks, and optional color.
  • Containers: write JSON to stdout and rely on Docker, Kubernetes, or the hosting platform to collect logs.
  • Server processes: use a process manager or log forwarder for rotation and shipping instead of manually managing log files in app code.
  • External platforms: map Pino fields to the destination’s expected schema, especially severity, timestamp, trace ID, and error fields.

Production configuration checklist

Production logging should be explicit, consistent, and safe. Set the log level from configuration, commonly with an environment variable such as LOG_LEVEL=info. Use debug or trace only for short investigations, because verbose logs can increase storage cost and expose sensitive implementation details. Add a service name, version, environment, and region as base fields so logs from mulle services can be filtered reliably. If your system uses distributed tracing, include trace_id and span_id in request logs so logs can be correlated with traces and metrics.

Concern Recommended practice
Readable local logs Enable pino-pretty only outside production.
Production ingestion Emit newline-delimited JSON to standard output.
Log volume Default to info, raise verbosity temporarily, and sample noisy events.
Sensitive data Redact passwords, tokens, cookies, authorization headers, and personal data.
Correlation Attach request IDs, trace IDs, service names, and deployment metadata.

Redaction deserves special attention. Pino supports redacting fields before logs are written, which helps prevent secrets from reaching terminals, files, or third-party systems. Configure redaction for paths such as req.headers.authorization, req.headers.cookie, password, token, and payment or identity fields. Also avoid logging entire request bodies by default; log stable identifiers and validation outcomes instead. With structured JSON, controlled levels, safe transports, and consistent correlation fields, Pino becomes more than a console logger: it becomes a core part of application observability.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Should I use Pino instead of Winston for a Node.js application?

Pino is usually a better choice when performance and structured JSON logs are priorities. It writes logs with very low overhead and works well with log platforms like Datadog, Better Stack, Elastic, Loki, and CloudWatch. Winston can still be useful if you need many built-in transports directly in the logger, but Pino’s transport model is typically preferred for production services.

What log level should I use in production?

Most production Node.js applications should use info as the default log level. Use debug locally or temporarily when investigating an issue, and reserve trace for very detailed diagnostics because it can produce a large volume of logs. Use warn for recoverable problems and error when an operation fails or needs attention.

How should I log errors with Pino so stack traces are included?

Pass the error object as the first argument to the log method, such as logger.error(err, 'Database query failed'). Pino serializes the error message, type, and stack trace in a structured format that log tools can parse. Avoid logging only err.message, because that removes useful debugging context.

Should Pino logs be pretty-printed in production?

No, production logs should usually stay as JSON because they are easier for log collectors and observability platforms to parse. Pretty printing is best for local development, where humans are reading logs directly in the terminal. A common setup is to use pino-pretty only when NODE_ENV is not production.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I add request IDs to logs with Pino HTTP?

Use pino-http and configure a request ID with an existing header such as x-request-id, or generate one when the header is missing. Include that ID in every request log so you can trace all entries related to a single API call. This is especially useful when debugging errors across load-balanced services, background jobs, or downstream API calls.

Bottom Line

Pino gives Node.js applications fast, structured logging that works well from local development through production. By choosing appropriate log levels, logging errors with context, adding request logging, and routing output through transports, you create logs that are easier to search, analyze, and act on.

The next step is to standardize your logging approach across the app: define your log format, include useful metadata, avoid sensitive data, and connect your logs to your observability stack. With that foundation in place, debugging incidents and understanding application behavior becomes much faster and more reliable.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.