Effective logging and monitoring are critical components of a production-grade Express.js application. By using logging, you can track activities, debug issues, and gain insights into how users are interacting with your application. Monitoring allows you to track the health, performance, and usage of your application in real-time, helping to identify potential issues before they impact users.
Logging records events in your application, such as requests, errors, and user activities. Monitoring, on the other hand, involves tracking metrics like response times, server uptime, and error rates. Together, they provide crucial insights into the health and performance of your application.
Express.js makes it easy to add simple logging to applications using console.log
to track events. However, this approach is limited in functionality and flexibility.
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
next();
});
app.get('/', (req, res) => {
res.send('Home Page');
});
app.listen(3000, () => console.log('Server running on port 3000'));
Explanation: This middleware logs the current date and time, HTTP method, and URL for each request. While console.log
is helpful for basic logging, it lacks advanced features, which leads us to more advanced tools.
Winston is a versatile and customizable logging library commonly used in Node.js applications. It allows different log levels, output formats, and transport options (e.g., console, file, or database).
npm install winston
const express = require('express');
const app = express();
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
winston.format.printf(({ timestamp, level, message }) => {
return `${timestamp} [${level}]: ${message}`;
})
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'combined.log' })
]
});
app.use((req, res, next) => {
logger.info(`${req.method} ${req.url}`);
next();
});
app.get('/', (req, res) => {
res.send('Home Page');
});
app.listen(3000, () => logger.info('Server running on port 3000'));
winston
to log at the info
level and above.combined.log
.Morgan is a popular HTTP request logger middleware for Node.js. It provides a streamlined way to log HTTP requests and is often used alongside other logging tools like Winston.
npm install morgan
const morgan = require('morgan');
// Log requests to the console
app.use(morgan('combined'));
Morgan provides several predefined formats, including:
combined
: Standard Apache combined log output (IP, date, HTTP method, URL, status, response time, etc.)short
: Shorter format with less information.
::1 - - [10/Nov/2024:08:00:00 +0000] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0"
This output provides detailed information about each request, which is helpful in production environments.
The ELK Stack (Elasticsearch, Logstash, and Kibana) is a powerful combination for centralized logging and analysis.
winston-logstash
to send logs to Logstash.
const LogstashTransport = require('winston-logstash');
logger.add(new LogstashTransport({ host: 'logstash-host', port: 5000 }));
With the ELK stack, you can visualize logs on Kibana dashboards, making it easier to track metrics, error patterns, and performance bottlenecks.
Prometheus is an open-source monitoring tool that scrapes metrics from applications, and Grafana is a data visualization tool used to create interactive dashboards.
prom-client
library:
npm install prom-client
prom-client
with Express.js to expose metrics.
const client = require('prom-client');
const counter = new client.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status']
});
app.use((req, res, next) => {
res.on('finish', () => {
counter.labels(req.method, req.route ? req.route.path : req.path, res.statusCode).inc();
});
next();
});
app.get('/metrics', async (req, res) => {
res.set('Content-Type', client.register.contentType);
res.end(await client.register.metrics());
});
This example increments a counter for each request and exposes a /metrics
endpoint for Prometheus to scrape.
Sentry is a powerful error-tracking tool that provides detailed error logs, stack traces, and performance metrics.
npm install @sentry/node
const Sentry = require('@sentry/node');
Sentry.init({ dsn: 'YOUR_SENTRY_DSN' });
app.use(Sentry.Handlers.requestHandler());
app.get('/', (req, res) => {
res.send('Home Page');
});
app.use(Sentry.Handlers.errorHandler());
Sentry captures errors automatically, which you can view in the Sentry dashboard. This helps you track unresolved errors and improve application stability.
Logging and monitoring are indispensable for Express.js applications. From basic console logging to advanced centralized logging with ELK, each tool adds value and insight into application performance. Using monitoring tools like Prometheus and Grafana, along with error tracking with Sentry, enables you to respond to issues promptly and ensure optimal application performance. Happy Coding!❤️