Logging #
Logging is an essential practice in Node.js development, providing valuable insights into application behavior, errors, and performance. Here’s a comprehensive overview of basic logging in Node.js:
Console Logging: #
The simplest form of logging is using the console object, which has methods like log, error, and warn.
console.log('This is a log message.');
console.error('This is an error message.');
console.warn('This is a warning message.');
Custom Logging with Winston: #
Winston is a popular logging library for Node.js, offering flexible and customizable logging options.
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.simple(),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'logfile.log' })
]
});
logger.info(‘This is an info message.'); logger.error(‘This is an error message.');
Logging Levels: #
Logging levels help categorize log messages by severity. Common levels include info, warn, error, and debug. Winston allows setting the log level for different transports.
logger.debug('This is a debug message.');
Express Middleware for Request Logging: #
In an Express.js application, middleware can be used to log incoming requests and responses.
const express = require('express');
const morgan = require('morgan');
const app = express();
app.use(morgan('dev')); // 'dev' format for concise logging
app.get('/', (req, res) => {
res.send('Hello, Node.js!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Logging with Timestamps: #
Including timestamps in log messages helps in tracking when events occurred.
const winston = require('winston');
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.simple()
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'logfile.log' })
]
});
logger.info('Log message with timestamp.');
Logging Unhandled Exceptions: #
Logging unhandled exceptions is crucial for identifying and addressing unexpected errors.
process.on('uncaughtException', (error) => {
logger.error('Uncaught Exception:', error.message);
// Additional cleanup or termination logic
process.exit(1);
});
Logging with Winston and Express Middleware: #
Combining Winston with Express middleware enables centralized logging for an application.
const express = require('express');
const winston = require('winston');
const morgan = require('morgan');
const app = express();
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.simple()
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'logfile.log' })
]
});
app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } }));
app.get('/', (req, res) => {
res.send('Hello, Node.js!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Log Rotation: #
Implement log rotation to manage log file sizes and prevent unlimited log growth.
const winston = require('winston');
require('winston-daily-rotate-file');
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.simple()
),
transports: [
new winston.transports.Console(),
new winston.transports.DailyRotateFile({
filename: 'logs/%DATE%-logfile.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d'
})
]
});
logger.info('Log message with rotation.');
Logging is a crucial tool for debugging, monitoring, and maintaining Node.js applications. Whether using simple console logging or sophisticated libraries like Winston, adopting a consistent logging strategy enhances the developer’s ability to diagnose issues and improve overall application health.