3.12 — Quick Revision: Logging and Monitoring
Your cheat sheet for log levels, Winston configuration, Morgan formats, error handling patterns, and monitoring tools. Bookmark this page for quick reference.
< Interview Questions | README >
Log Levels (Severity Order)
| Level | Priority | When to Use | Example |
|---|
error | 0 (highest) | Something broke | DB connection lost |
warn | 1 | Potential issue | Slow query, deprecation |
info | 2 | Normal events | User login, order placed |
http | 3 | HTTP requests | GET /api/users 200 45ms |
debug | 4 | Dev debugging | Variable values |
silly | 5 (lowest) | Verbose tracing | Loop iterations |
Setting level = "warn" logs: error + warn (suppresses info, debug, silly)
Recommended Levels by Environment
| Environment | Level | Format |
|---|
| Development | debug | Colorized console |
| Testing | error | Minimal/silent |
| Staging | info | JSON files |
| Production | warn or info | JSON files + aggregator |
Winston Setup
const winston = require("winston");
require("winston-daily-rotate-file");
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || "info",
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
defaultMeta: { service: "my-api" },
transports: [
new winston.transports.DailyRotateFile({
filename: "logs/combined-%DATE%.log",
datePattern: "YYYY-MM-DD",
maxFiles: "14d",
zippedArchive: true,
}),
new winston.transports.DailyRotateFile({
filename: "logs/error-%DATE%.log",
level: "error",
datePattern: "YYYY-MM-DD",
maxFiles: "30d",
}),
],
});
if (process.env.NODE_ENV !== "production") {
logger.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
),
}));
}
Winston Transports
| Transport | Purpose | Key Options |
|---|
Console | Terminal output | format, level |
File | Write to file | filename, level, maxsize, maxFiles |
DailyRotateFile | Daily file rotation | datePattern, maxSize, maxFiles, zippedArchive |
Http | Send to endpoint | host, port, path |
Winston Formats
| Format | Purpose | Environment |
|---|
format.json() | Structured JSON output | Production |
format.simple() | level: message | Basic/testing |
format.colorize() | Color-coded levels | Development |
format.timestamp() | Add timestamp field | All |
format.errors({ stack: true }) | Include stack traces | All |
format.printf(fn) | Custom format function | Custom |
format.combine(...) | Chain multiple formats | All |
Morgan Formats
| Format | Output Example | Best For |
|---|
dev | GET /api/users 200 45.123 ms (colorized) | Development |
combined | Full Apache format with referrer + user-agent | Production |
common | Apache common (no referrer/agent) | Production |
short | Shorter than combined | General |
tiny | GET /api/users 200 1234 - 45.123 ms | Simple |
Morgan + Winston Integration
const morgan = require("morgan");
app.use(morgan("combined", {
stream: { write: (msg) => logger.http(msg.trim()) },
skip: (req) => req.url === "/health",
}));
Request ID Middleware
const { v4: uuidv4 } = require("uuid");
app.use((req, res, next) => {
req.id = req.headers["x-request-id"] || uuidv4();
res.setHeader("x-request-id", req.id);
next();
});
Error Handling Middleware
app.use((err, req, res, next) => {
logger.error("Request error", {
error: err.message,
stack: err.stack,
method: req.method,
url: req.originalUrl,
requestId: req.id,
userId: req.user?._id,
});
const status = err.statusCode || 500;
res.status(status).json({
status: "error",
message: status === 500 ? "Internal server error" : err.message,
});
});
Process-Level Error Handlers
process.on("unhandledRejection", (reason) => {
logger.error("Unhandled Rejection", {
error: reason instanceof Error ? reason.message : reason,
stack: reason instanceof Error ? reason.stack : undefined,
});
});
process.on("uncaughtException", (err) => {
logger.error("Uncaught Exception", { error: err.message, stack: err.stack });
process.exit(1);
});
What to Log vs What NOT to Log
Always Log
| Event | Level |
|---|
| Server start/stop | info |
| User auth (login/logout/failure) | info / warn |
| API errors (4xx, 5xx) | warn / error |
| Database errors | error |
| External API calls (time + status) | info |
| Business events (orders, payments) | info |
| Slow queries/responses | warn |
Never Log
| Data | Reason |
|---|
| Passwords | Security |
| API keys / tokens | Security |
| Credit card numbers | PCI compliance |
| SSN / personal health data | Privacy laws |
| Full request bodies with PII | Data protection |
Monitoring Tools Overview
| Tool | Type | Purpose |
|---|
| Sentry | Error monitoring | Capture errors, stack traces, affected users |
| LogRocket | Session replay | See what the user saw (frontend) |
| ELK Stack | Log aggregation | Centralized search + dashboards |
| Datadog | Full observability | Metrics, logs, traces, dashboards |
| CloudWatch | AWS logging | AWS-native log management |
| Prometheus + Grafana | Metrics | Real-time metrics and alerting |
| Papertrail | Cloud logging | Simple log aggregation |
ELK Stack Components
| Component | Role |
|---|
| Elasticsearch | Store + index + search logs |
| Logstash | Ingest + transform + route logs |
| Kibana | Visual dashboard + search UI |
| Filebeat | Lightweight log file shipper |
Quick Debugging Checklist
Library Comparison
| Feature | Winston | Pino | Morgan |
|---|
| Type | General logger | General logger | HTTP logger |
| Speed | Moderate | Fastest | N/A |
| Formats | Multiple | JSON | Predefined strings |
| Transports | Built-in | Separate process | Stream |
| Express | Manual | pino-http | Built-in middleware |
| Best for | Most apps | High-throughput | HTTP access logs |
| Common combo | Winston + Morgan | Pino + pino-http | With Winston/Pino |