Effective logging is essential for debugging, monitoring, and understanding your application's behavior in production. Simply using `console.log` is not enough for a serious application.
1. Use a Dedicated Logging Library
Libraries like Winston or Pino are designed for robust logging. They offer features like log levels, custom transports (e.g., writing to files, databases, or logging services), and structured formatting.
2. Use Log Levels
Different log messages have different levels of severity. Using levels allows you to filter logs and quickly identify critical issues.
- `error`: For unrecoverable errors that require immediate attention.
- `warn`: For potential issues that don't crash the app.
- `info`: For general application flow messages.
- `debug`: For detailed information useful only during development.
3. Log in a Structured Format (JSON)
Logging in JSON format makes your logs machine-readable. This is crucial for log management systems like Datadog, Splunk, or the ELK stack to parse, index, and search your logs effectively.
Example with Winston
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
// Write all logs with level `error` or less to `error.log`
new winston.transports.File({ filename: 'error.log', level: 'error' }),
// Write all logs with level `info` or less to `combined.log`
new winston.transports.File({ filename: 'combined.log' }),
],
});
// If we're not in production then log to the `console`
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple(),
}));
}
logger.info('Server started');
logger.warn('Configuration file not found, using defaults.');
logger.error('Failed to connect to database.');
Comments
Post a Comment