When an AI coding assistant helps you debug a production issue, it reads your logs. If those logs are scattered console.log calls with inconsistent formatting, it can't do much. It doesn't know which lines belong to the same request, what the timing was, or what the error context means.
Evlog is a structured logging library by Hugo Richard, built around the "wide event" pattern: one structured event per request, with all context attached. I've been using it in my projects. It is especially useful when debugging with AI tools, because the output is machine-readable by design.
The problem with console.log
A typical Node.js app logs like this:
[INFO] Processing order 12345
[INFO] User: john@example.com
[DEBUG] Fetching inventory for SKU-789
[WARN] Inventory low: 3 remaining
[INFO] Order processed in 847ms
[ERROR] Failed to send confirmation emailThat is six lines for one request. To understand what happened, you have to stitch them together in your head, match the timing, and work out which lines belong to which request when 50 users are hitting the service at once.
An AI assistant reading these logs has the same problem, only worse. Without explicit correlation, it can't infer the causal chain between lines.
One event per request
Evlog flips the model. Instead of many log calls, you build up a single event over the life of the request:
import { createRequestLogger } from 'evlog'
export default defineEventHandler(async (event) => {
const log = createRequestLogger(event)
log.field('user', user.email)
log.field('orderId', orderId)
const items = await fetchInventory(skus)
log.field('inventoryCount', items.length)
if (items.some(i => i.stock < 5)) {
log.field('lowStock', true)
}
await processOrder(order)
// Duration is tracked automatically from request start
// The event emits on request end with all fields attached
})When the request finishes, evlog emits one JSON event:
{
"level": "info",
"message": "POST /api/orders",
"timestamp": "2026-03-05T10:23:45.123Z",
"duration": 847,
"user": "john@example.com",
"orderId": 12345,
"inventoryCount": 3,
"lowStock": true,
"env": { "service": "api", "environment": "production" }
}Every field sits on the same event, and duration comes for free. An assistant can read one object and see the whole request: who made it, what happened, how long it took, and what was unusual.
Errors that explain themselves
The feature that helps AI debugging most is evlog's error structure. Instead of throw new Error("Failed to sync"), you create errors with why and fix fields:
throw new EvlogError({
message: 'Failed to sync repository',
status: 503,
why: 'GitHub API rate limit exceeded',
fix: 'Wait 1 hour or use a different token',
link: 'https://docs.github.com/en/rest/rate-limit',
cause: originalError,
})When an AI reads this error in a log, it gets context it usually lacks:
- What happened: the message.
- Why it happened: the root cause.
- How to fix it: a concrete next step.
That is the difference between an assistant saying "there's an error on line 47" and saying "the GitHub sync failed because you exceeded the rate limit; wait an hour or switch to a different API token."
Context without the wiring
Evlog's framework integrations for Nuxt, Next.js, Express, Fastify, Hono and SvelteKit attach request context automatically:
- Request method and path, from the HTTP layer
- Duration, from request start to response end
- Status code, from the response
- Environment details such as service name, deployment version, commit hash and region, from runtime detection
In Nuxt it takes one module entry:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['evlog/nuxt'],
evlog: {
env: { service: 'my-app' },
},
})Every server route then gets a request logger with duration tracking. There is nothing to import and no middleware to set up; the module injects it.
Why this matters when AI does the debugging
Developers now paste production logs into Claude or ChatGPT and ask what went wrong. The answer can only be as good as the logs.
Structured events with correlation, timing and self-describing errors give the model what it needs to reason about the problem. Scattered console.log calls force it to guess how lines relate, and it often guesses wrong.
So log format is a question of machine readability now, as well as human readability. JSON events with a consistent structure, automatic context and explicit error causes work for both readers.