Logging with Morgan and Winston
8 min read
Logging with Morgan and Winston
Good logging is essential for debugging in production. There are two distinct logging concerns in an Express API: HTTP request logging (which route was hit, how long it took, what status was returned) and application logging (business events, errors, debug info).
HTTP Request Logging with Morgan
bash
npm install morgan
npm install --save-dev @types/morganjs
import morgan from "morgan";
// "dev" format: METHOD url STATUS response-time
app.use(morgan("dev"));
// "combined" is better for production (Apache log format)
// app.use(morgan("combined"));Structured Application Logging with Winston
js
import { createLogger, format, transports } from "winston";
export const logger = createLogger({
level: process.env.LOG_LEVEL || "info",
format: format.combine(
format.timestamp(),
format.json()
),
transports: [
new transports.Console(),
new transports.File({ filename: "logs/error.log", level: "error" })
]
});
// Usage in a route
logger.info("User created", { userId: 42, email: "alice@example.com" });
logger.error("Database connection failed", { err: err.message });Use structured JSON logs in production so that log aggregation platforms (Datadog, Grafana Loki, AWS CloudWatch) can parse and query fields like userId or statusCode without regex.
Ready to test yourself?
Practice Express— quiz & coding exercises