在 Node.js 应用中,日志轮转(Log Rotation)是管理日志文件的重要策略,主要目的是控制日志文件大小、避免磁盘空间耗尽、简化历史日志管理。以下是常见的实现方案和技术细节:
一、核心轮转策略
- 按时间切割
- 每日/每小时生成新日志文件(如
app-2023-10-01.log
) - 适用场景:高频日志且需按时间维度分析
- 每日/每小时生成新日志文件(如
- 按文件大小切割
- 当日志文件达到阈值(如 100MB)时创建新文件
- 适用场景:日志量波动大,需严格控制单文件大小
- 混合策略
- 同时满足时间或大小任一条件即触发轮转
- 例如:每天或文件超过 1GB 时切割
二、主流实现方案
方案 1:使用日志库内置功能
-
Winston +
winston-daily-rotate-file
const winston = require('winston'); require('winston-daily-rotate-file'); const transport = new winston.transports.DailyRotateFile({ filename: 'app-%DATE%.log', datePattern: 'YYYY-MM-DD', maxSize: '100m', // 可选大小限制 maxFiles: '14d' // 保留最近14天日志 }); const logger = winston.createLogger({ transports: [transport] });
-
Log4js
const log4js = require('log4js'); log4js.configure({ appenders: { file: { type: 'dateFile', filename: 'app.log', pattern: '-yyyy-MM-dd', maxLogSize: 10485760 // 10MB } }, categories: { default: { appenders: ['file'], level: 'info' } } });
方案 2:使用系统工具
-
Linux Logrotate
- 配置
/etc/logrotate.d/nodeapp
:/var/log/nodeapp/*.log { daily rotate 7 compress missingok copytruncate # 避免重启应用 }
- 优点:与语言无关,可管理多个日志文件
- 配置
-
PM2 内置日志管理
- 通过 PM2 启动应用时自动轮转:
pm2 start app.js --log-date-format "YYYY-MM-DD HH:mm" --log /var/log/app.log pm2 reloadLogs # 手动触发轮转
- 通过 PM2 启动应用时自动轮转:
三、关键注意事项
- 文件写入连续性
- 使用
copytruncate
(Logrotate)或create+reopen
(代码库)避免日志丢失 - 示例:Node.js 收到
SIGHUP
信号时重新打开日志流process.on('SIGHUP', () => { logger.transports.forEach(transport => transport.reopen()); });
- 使用
- 异常处理
- 监控日志写入失败(如权限问题、磁盘满)
- 性能影响
- 高频日志需测试轮转时的 I/O 压力
- 归档与压缩
- 自动压缩旧日志(如
.gz
)节省磁盘空间
- 自动压缩旧日志(如
四、实践建议
- 测试轮转流程:确保切割后新日志能正确写入
- 统一命名规范:如
app-[timestamp]-[index].log
- 监控报警:对日志体积增长异常设置阈值警报
- 清理策略:结合业务保留周期(如 GDPR 合规)
根据项目规模,小型应用可直接使用 winston
/log4js
方案,大型分布式系统建议结合 Logrotate
或日志收集服务(如 ELK、Fluentd)实现集中管理。
(牛站网络)