发布于2026-07-12 阅读(0)
扫一扫,手机访问
说到 Linux 环境下 Node.js 应用的日志清理,其实并不复杂,但里面的门道也不少。很多开发者在初期往往容易忽略这个问题,等到磁盘告警的时候才手忙脚乱。下面我梳理了几个业界主流的方案,从系统级到应用级,再到兜底策略,你可以根据实际场景灵活组合。

先分享几个核心判断。如果你追求稳定、运维成本低,那 logrotate 肯定是首选——它是操作系统层面的日志轮转工具,按日期、按大小切分、压缩、保留份数,这些基本操作它都能搞定,而且和系统生态融合得特别好。如果你的业务逻辑对日志切割时机有特殊要求,比如按小时切分,或者需要在切割时触发某些业务动作,那在应用代码里用 winston + winston-daily-rotate-file 或者 pino 这类日志库内置轮转功能,会更灵活。如果你用的是 PM2 部署,那直接用它的 pm2-logrotate 插件就对了,托管方便,配置统一。另外,如果你已经接入了 systemd 管理服务,那 journald 天然就带日志轮转能力,配合 rsyslog 落地到文件后再交给 logrotate 管理,也是一条成熟路径。最后,不管用了什么方案,都强烈建议加一个 cron 定时任务 做兜底清理——毕竟“防患于未然”在运维里永远是值得的。
如果你决定用 logrotate,配置起来很简单。直接在 /etc/logrotate.d/ 下新建一个配置文件,比如命名为 node-app,然后写入以下内容:
/var/log/node-app/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 root adm
copytruncate
dateext
}
这段配置的意思是:每天轮转一次,保留最近 7 份日志,旧的日志会被压缩,但压缩会延迟一次(即保留一份未压缩的日志方便排查),如果日志文件缺失也不报错,空文件不轮转,轮转后按原权限创建一个新文件,并且使用 copytruncate 模式——这个模式的好处是,应用持有的文件句柄不会受影响,无需重启服务,不过在高并发写入时可能会有少量日志丢失,视情况权衡。配置完成后,可以用 sudo logrotate -f /etc/logrotate.d/node-app 手动强制执行一下测试。
如果你希望在应用层控制轮转,winston 配合 winston-daily-rotate-file 是最常见的做法。先装包:
npm i winston winston-daily-rotate-file
然后配置:
const winston = require('winston');
const DailyRotateFile = require('winston-daily-rotate-file');
const transport = new DailyRotateFile({
filename: '/var/log/node-app/application-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d'
});
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [transport]
});
这里按小时切割,大于 20MB 也会触发轮转,压缩归档,日志最多保留 14 天。如果你想按大小触发,而不依赖时间,只需要调整 datePattern 或者改用其他参数组合即可。
如果你用 PM2 管理进程,那用它自带的日志轮转插件是最省心的。安装:
pm2 install pm2-logrotate
然后配置参数:
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true
pm2 set pm2-logrotate:rotateInterval "0 0 * * *"
pm2 restart all
这样设置后,日志文件超过 10MB 或者每天凌晨 0 点都会触发轮转,保留最近 7 份,并启用压缩。配置很直观,适合中小规模的 PM2 项目。
如果你用 systemd 管理 Node.js 服务,可以在 service 文件里把日志输出到文件:
[Service]
ExecStart=/usr/bin/node /path/to/app.js
StandardOutput=append:/var/log/node-app/stdout.log
StandardError=append:/var/log/node-app/stderr.log
SyslogIdentifier=node-app
当然,更推荐的方式是接入 syslog,在 rsyslog 配置中添加规则:
if $programname == 'node-app' then /var/log/node-app.log
& stop
这样所有日志集中到一个文件,后续再交给 logrotate 统一管理。别忘了 sudo systemctl daemon-reload && sudo systemctl restart node-app 来使配置生效。
最后,无论你用了上面哪种方案,我都建议加一个 crontab 任务作为最后一道安全网。比如每天凌晨清理 7 天前的 .log 文件:
0 0 * * * find /var/log/node-app -type f -name "*.log" -mtime +7 -delete
或者写成脚本 /opt/scripts/clean_logs.sh,然后定时调用:
0 1 * * * /opt/scripts/clean_logs.sh
这个方案的好处是简单粗暴,能应对所有“意外情况”——比如轮转脚本执行失败、日志突增导致磁盘迅速打满等。建议把它当作“有限责任公司的破产清算”,平时不显山露水,关键时候能救命。
find ... -mtime +7 -print 打印一下将要被删除的文件列表,确认无误后再执行删除。生产环境谨慎一点总没错。copytruncate 模式能绕过这个问题,但高并发下可能丢日志。如果应用支持信号重开日志(比如向进程发送 SIGUSR1),那轮转后通知应用重开是更优雅的做法。0640 root adm,避免被非授权用户读取或篡改。compress 能显著节省空间,rotate 7 或 maxFiles '14d' 这些值不是拍脑袋定的——你得根据日志平均日增长量、磁盘剩余空间、合规要求(比如某些场景要求日志保留 180 天)来综合计算,并且定期审计是否合理。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8