patternjavascriptModerate
Structured logging: JSON logs for machine-readable observability
Viewed 0 times
structured loggingJSON logspinowinstonobservabilitylog aggregationcorrelation ID
Problem
Text-based logs are difficult to search, filter, and aggregate in log management systems. Finding all errors for a specific user or request requires complex regex.
Solution
Use structured JSON logging with a library like pino:
import pino from 'pino';
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
// Pretty print in development
transport: process.env.NODE_ENV === 'development'
? { target: 'pino-pretty' }
: undefined,
base: {
service: 'myapp',
version: process.env.APP_VERSION,
env: process.env.NODE_ENV,
},
});
// Use structured fields, not string interpolation
// BAD:
logger.info(`User ${userId} created order ${orderId}`);
// GOOD:
logger.info({ userId, orderId, amount }, 'Order created');
// Output: {"level":"info","userId":"u_123","orderId":"o_456","amount":1999,"msg":"Order created"}
// Request logging middleware
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
logger.info({
method: req.method,
path: req.path,
status: res.statusCode,
durationMs: Date.now() - start,
correlationId: req.headers['x-correlation-id'],
}, 'HTTP request');
});
next();
});Why
JSON logs allow log aggregators (Datadog, CloudWatch, Loki) to index individual fields. You can query 'all errors where userId = X in the last hour' in seconds instead of grep-ing through files.
Gotchas
- Never log sensitive data: passwords, tokens, PII, card numbers — even in debug mode
- Use log levels correctly: debug (verbose), info (normal operations), warn (potential problems), error (actionable failures)
- pino is 5x faster than winston and outputs proper JSON — use it for new projects
- In production, log to stdout and let the container/systemd collect it — don't write to files directly
Revisions (0)
No revisions yet.