Introduction
evlog is a TypeScript logging library that replaces scattered log lines with comprehensive wide events and structured errors.
Inspired by Logging Sucks by Boris Tane.
Philosophy
Traditional logging is broken. Your logs are scattered across dozens of files, each request generates 10+ log lines, and when something goes wrong, you're left grep-ing through noise hoping to find signal.
evlog takes a different approach:
Wide Events
Structured Errors
Request Scoping
Pretty for Dev
What are Wide Events?
Instead of scattering logs throughout your code:
logger.info('Request started')
logger.info('User authenticated', { userId: user.id })
logger.info('Fetching cart', { cartId: cart.id })
logger.info('Processing payment')
logger.info('Payment successful')
logger.info('Request completed')
You accumulate context and emit once:
// server/api/checkout.post.ts
const log = useLogger(event)
log.set({ user: { id: 1, plan: 'pro' } })
log.set({ cart: { id: 42, items: 3, total: 9999 } })
log.set({ payment: { method: 'card', status: 'success' } })
return { success: true }
[INFO] POST /api/checkout (234ms)
user: { id: 1, plan: 'pro' }
cart: { id: 42, items: 3, total: 9999 }
payment: { method: 'card', status: 'success' }
status: 200
One log, all context. Everything you need to understand what happened during that request.
Structured Errors
Traditional errors are opaque:
throw new Error('Payment failed')
Structured errors provide actionable context:
// server/api/checkout.post.ts
import { createError } from 'evlog' // Use 'evlog/nitro/v3' for Nitro v3
throw createError({
message: 'Payment failed',
status: 402,
why: 'Card declined by issuer (insufficient funds)',
fix: 'Try a different payment method or contact your bank',
link: 'https://docs.example.com/payments/declined',
})
{
"statusCode": 402,
"message": "Payment failed",
"data": {
"why": "Card declined by issuer (insufficient funds)",
"fix": "Try a different payment method or contact your bank",
"link": "https://docs.example.com/payments/declined"
}
}
With why, fix, and link fields, anyone debugging—human or AI—can immediately understand the root cause and how to resolve it.
Why Context Matters
We're entering an era where AI agents build, debug, and maintain applications. These agents need structured context to work effectively:
why: The root cause, so the agent understands what went wrongfix: An actionable solution the agent can suggest or applylink: Documentation for complex issues
Traditional console.log and generic throw new Error() provide no actionable context. evlog's structured output is designed for both humans and AI to parse and act on.
Next Steps
- Installation - Install evlog in your project
- Quick Start - Get up and running in minutes