选择合适的日志库
使用成熟的日志库(如Winston、Bunyan、Pino)是提升日志可读性的基础。这些库提供日志级别管理、多输出目标(控制台、文件、远程服务器)、格式化等功能。例如,Winston支持灵活的格式化配置,Bunyan默认以JSON格式输出便于分析,Pino则以高性能著称,适合对日志性能要求高的场景。
配置合理的日志级别
根据环境设置不同的日志级别,避免无关日志干扰。例如:
warn或error,仅记录关键错误和警告,减少日志文件大小;debug或info,记录详细信息以辅助调试。logger.level属性动态调整级别(如process.env.NODE_ENV === 'production' ? 'warn' : 'debug')。结构化日志格式
采用结构化日志(如JSON格式)代替普通文本日志,便于后续解析和分析。结构化日志包含时间戳、日志级别、消息、模块名称、请求ID等元数据,例如:
{
"timestamp": "2025-10-05 14:30:00",
"level": "INFO",
"message": "User logged in",
"userId": 123,
"module": "auth"
}
使用Winston时,可通过winston.format.combine组合timestamp、json等格式化器;使用Pino时,默认输出JSON格式。
自定义日志格式
通过格式化器定制日志输出样式,增强可读性。例如,使用Winston的printf格式化器添加时间戳、颜色和固定格式:
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.colorize(),
winston.format.printf(({ timestamp, level, message }) => {
return `${timestamp} ${level.toUpperCase()}: ${message}`;
})
),
transports: [new winston.transports.Console()]
});
输出结果:2025-10-05 14:30:00 INFO: User logged in(带颜色区分级别)。
启用日志轮转
使用日志轮转工具(如winston-daily-rotate-file或系统logrotate)自动管理日志文件,防止单个文件过大。例如,Winston的daily-rotate-file传输可按天分割日志:
const winston = require('winston');
require('winston-daily-rotate-file');
const transport = new winston.transports.DailyRotateFile({
filename: 'logs/application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m',
maxFiles: '14d'
});
const logger = winston.createLogger({
transports: [transport]
});
系统logrotate可通过配置文件(如/etc/logrotate.d/nodejs)实现类似功能。
集中式日志管理
将日志发送到集中式日志管理系统(如ELK Stack、Graylog、Fluentd),实现日志的统一存储、搜索和分析。例如,使用Winston的file传输将日志写入本地文件,再通过Logstash收集到Elasticsearch,通过Kibana可视化分析。集中式管理便于跨服务、跨服务器的日志关联,提升故障排查效率。
添加色彩与样式
为终端输出的日志添加颜色,增强视觉区分度。例如,Winston的colorize格式化器可根据日志级别显示不同颜色(错误为红色、警告为黄色、信息为绿色):
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
),
transports: [new winston.transports.Console()]
});
输出结果:info: User logged in(绿色)、error: Something went wrong(红色)。
编写清晰的日志注释
在日志记录代码中添加注释,说明日志的用途和上下文。例如:
// 记录用户登录成功事件,包含用户ID和IP地址
logger.info(`User logged in - UserID: ${userId}, IP: ${req.ip}`, { userId, ip: req.ip });
注释能帮助其他开发者快速理解日志含义,提升日志的可维护性。