Script Valley
REST API Development: Complete Course from Beginner to Production
Production and Best Practices: Logging, Monitoring, Documentation, and DeploymentLesson 6.1

Structured Logging and Error Monitoring

structured logging, Winston, Pino, log levels, correlation ID, centralized logging, Sentry, error tracking, production logging

Structured Logging and Error Monitoring

In production, console.log is not enough. You need structured logs that can be searched and aggregated, and an error tracking system that alerts you the moment something breaks. This lesson covers the logging and monitoring setup used by professional engineering teams.

DiagramStructured Logging Flow

IMAGE PROMPT (replace this block with your generated image):

Flat pipeline diagram on white background. Title: Structured Logging and Observability Pipeline. Left to right flow. Step 1: HTTP Request box with correlation ID badge (UUID icon). Step 2: Express API Server box (fill #3A5EFF, white text) — internally shows four log level pills stacked: ERROR (red), WARN (amber), INFO (blue), DEBUG (gray). Arrow to the right splits into two branches. Branch 1 (top): arrow labeled JSON logs to Console and File Transport pointing to a Winston logo box, then another arrow to Cloud log box labeled Datadog / CloudWatch / Elasticsearch. Branch 2 (bottom): arrow labeled Unhandled errors pointing to Sentry box (Sentry logo or generic error box), which has an alert bell icon labeled Alerts team via email and Slack. Below all: a sample JSON log snippet box showing {level: error, message: User not found, userId: 42, correlationId: uuid-abc, timestamp: ISO}. Keys highlighted in #3A5EFF. White background, clean flow.

Why Structured Logging

Structured logs are JSON objects rather than plain text strings. Instead of "User 42 logged in at 10:30", you emit {"level": "info", "event": "user.login", "userId": "42", "timestamp": "2024-01-15T10:30:00Z", "ip": "192.168.1.1"}. Log aggregation tools can then query, filter, and visualize structured logs in ways impossible with plain text.

Logging with Winston

npm install winston

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
    new winston.transports.File({ filename: 'logs/combined.log' })
  ]
});

Correlation IDs

Add a unique ID to every request and include it in every log line generated during that request's processing. This allows you to trace the complete journey of a single request through your logs:

const { v4: uuidv4 } = require('uuid');

app.use((req, res, next) => {
  req.correlationId = req.headers['x-correlation-id'] || uuidv4();
  res.setHeader('X-Correlation-ID', req.correlationId);
  next();
});

Error Monitoring with Sentry

npm install @sentry/node

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,
  tracesSampleRate: 0.1
});

Sentry captures unhandled errors, groups them by stack trace, tracks frequency, and alerts your team via email or Slack. It also captures the request context for every error, making debugging dramatically faster.

Up next

API Documentation with OpenAPI and Swagger

Sign in to track progress