DEV Community

Atlas Whoff
Atlas Whoff

Posted on

Production Logging Strategy for Next.js: Pino, Sentry, and What Not to Log

Most Developers Log Too Much or Too Little

Too much: walls of debug logs that obscure real errors.
Too little: production breaks and you have no idea why.

Here's the logging strategy that scales from prototype to production.

Structured Logging with Pino

npm install pino pino-pretty
Enter fullscreen mode Exit fullscreen mode
// lib/logger.ts
import pino from 'pino'

const logger = pino({
  level: process.env.LOG_LEVEL ?? 'info',
  ...(process.env.NODE_ENV === 'development'
    ? { transport: { target: 'pino-pretty', options: { colorize: true } } }
    : {})
})

export default logger
export const createLogger = (context: string) => logger.child({ context })
Enter fullscreen mode Exit fullscreen mode

What to Log

const log = createLogger('stripe-webhook')

// Log structured data, not interpolated strings
log.info({ eventId: event.id, type: event.type }, 'Webhook received')

// Include request ID for tracing
log.info({
  requestId,
  userId: user.id,
  plan: subscription.plan,
  amount: invoice.amount_paid
}, 'Subscription payment processed')

// Error: always include the error object
log.error({ err, userId, eventId }, 'Failed to provision subscription')

// Debug only in development
log.debug({ query, params }, 'Database query')
Enter fullscreen mode Exit fullscreen mode

What NOT to Log

// Never log:
log.info({ password: user.password })          // Credentials
log.info({ token: req.headers.authorization }) // Auth tokens
log.info({ card: payment.cardNumber })         // PCI data
log.info({ ssn: user.ssn })                    // PII
log.info({ body: req.body })                   // Entire request bodies

// Log IDs, not values:
log.info({ userId: user.id, email: user.email }) // Email is borderline -- check your compliance
log.info({ stripeCustomerId: customer.id })      // OK -- not the card
Enter fullscreen mode Exit fullscreen mode

Request Tracing

// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'

export function middleware(request: NextRequest) {
  const requestId = uuidv4()
  const response = NextResponse.next()

  // Pass request ID downstream
  response.headers.set('x-request-id', requestId)
  request.headers.set('x-request-id', requestId)

  return response
}

// In API routes:
export async function POST(req: NextRequest) {
  const requestId = req.headers.get('x-request-id') ?? uuidv4()
  const log = logger.child({ requestId })

  log.info({ path: req.nextUrl.pathname }, 'Request started')
  // All subsequent logs include requestId automatically
}
Enter fullscreen mode Exit fullscreen mode

Error Tracking with Sentry

npm install @sentry/nextjs
npx @sentry/wizard@latest -i nextjs
Enter fullscreen mode Exit fullscreen mode
// instrumentation.ts
export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./sentry.server.config')
  }
  if (process.env.NEXT_RUNTIME === 'edge') {
    await import('./sentry.edge.config')
  }
}

// Capture errors with context
import * as Sentry from '@sentry/nextjs'

try {
  await processPayment(userId, amount)
} catch (err) {
  Sentry.captureException(err, {
    tags: { component: 'payment', userId },
    extra: { amount, currency }
  })
  throw err // Re-throw -- don't swallow errors
}
Enter fullscreen mode Exit fullscreen mode

Log Levels by Environment

Development: debug (everything)
Staging:     info (requests, events, errors)
Production:  warn + error only (reduce volume, reduce cost)
Enter fullscreen mode Exit fullscreen mode
// .env.production
LOG_LEVEL=warn

// .env.development
LOG_LEVEL=debug
Enter fullscreen mode Exit fullscreen mode

Alerting on Error Spikes

Sentry alerting rules:

  • Error rate > 1% of requests: page on-call
  • New error type first seen: Slack notification
  • Payment errors any rate: immediate alert

Pre-Built Logging in the AI SaaS Starter Kit

Comes with Pino configured, request ID middleware, Sentry integration, and structured logging patterns throughout.

$99 one-time at whoffagents.com

Top comments (0)