npm install pino pino-pretty
// logger.js
const pino = require('pino');
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
transport:
process.env.NODE_ENV === 'development'
? {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'HH:MM:ss',
}
}
: undefined, // JSON in production
});
module.exports = logger;
const { randomUUID } = require('crypto');
const logger = require('./logger');
function requestLogger(req, res, next) {
// Generate unique request ID
req.requestId = randomUUID();
req.startTime = Date.now();
// Create child logger with context
req.log = logger.child({
requestId: req.requestId,
method: req.method,
path: req.path,
userId: req.userId || 'anonymous',
});
req.log.info('Request started');
// Log when response finishes
res.on('finish', () => {
const duration =
Date.now() - req.startTime;
req.log.info({
statusCode: res.statusCode,
duration: `${duration}ms`,
}, 'Request completed');
});
next();
}
app.use(requestLogger);
// Must be LAST middleware
app.use((err, req, res, next) => {
const statusCode =
err.statusCode || 500;
// Log error with full context
req.log.error({
error: err.message,
stack: err.stack,
statusCode,
}, 'Unhandled error');
// Clean response to client
res.status(statusCode).json({
error: statusCode === 500
? 'Internal server error'
: err.message,
requestId: req.requestId,
// ^ user can reference this
// when contacting support
});
});
// ❌ BEFORE (useless in production)
console.log('upload started');
console.log(user);
console.log('error:', err);
// ✅ AFTER (searchable, traceable)
req.log.info({
action: 'upload_started',
fileSize: req.file.size,
mimeType: req.file.mimetype,
}, 'Image upload initiated');
req.log.error({
action: 'upload_failed',
error: err.message,
}, 'Image upload failed');
Build a React page at /admin/logs: read JSON log files from the server, parse each line, display in a table with columns: timestamp, level, userId, action, message. Add filters for log level and search by requestId.
git switch -c feature/PIXELCRAFT-067-structured-logging
git add server/ src/
git commit -m "Replace console.log with Pino structured logging (PIXELCRAFT-067)"
git push origin feature/PIXELCRAFT-067-structured-logging
# PR → Review → Merge → Close ticket ✅
Observability is how you understand production systems.
Logging is one of three "pillars of observability" — the tools that let you understand what your system is doing without stopping it.
console.log('here') — you have production-grade observability.