Skip to content

Instantly share code, notes, and snippets.

@waltervargas
Created March 12, 2026 01:27
Show Gist options
  • Select an option

  • Save waltervargas/2135992e5ab61087b2895e66aaea3576 to your computer and use it in GitHub Desktop.

Select an option

Save waltervargas/2135992e5ab61087b2895e66aaea3576 to your computer and use it in GitHub Desktop.

JSON Structured Logging for SvelteKit with Pino

Install

npm install pino

Create logger module

// src/lib/server/logger.ts
import pino from 'pino';

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

Usage

import { logger } from '$lib/server/logger';

// Instead of console.error('Failed to save match:', err);
logger.error({ err }, 'Failed to save match');

// Instead of console.log('User registered');
logger.info({ userId: user.id }, 'User registered');

Output

Pino outputs JSON by default with zero config:

{"level":50,"time":1710268800000,"err":{"message":"...","stack":"..."},"msg":"Failed to save match"}
{"level":30,"time":1710268800000,"userId":"abc123","msg":"User registered"}

Log Levels

Level Number Method
fatal 60 logger.fatal()
error 50 logger.error()
warn 40 logger.warn()
info 30 logger.info()
debug 20 logger.debug()
trace 10 logger.trace()

Tips

  • Set LOG_LEVEL=debug in dev, LOG_LEVEL=info in production
  • Always pass errors as { err } — Pino serializes stack traces automatically
  • Add context as the first argument object: logger.info({ userId, action }, 'message')
  • Works great with Dozzle — JSON logs are syntax-highlighted and filterable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment