Node.js 在 Debian 上的日志存储最佳实践
一 核心原则
- 采用结构化日志(如 JSON),便于检索、分析与可视化;在 生产环境将日志级别控制在 WARN/ERROR,按需开启 INFO/DEBUG,减少磁盘与 I/O 压力。
- 优先使用异步写入与多传输(文件、控制台、远程),避免阻塞主线程并提升高并发下的稳定性。
- 实施日志轮换与归档,防止单文件无限增长并控制磁盘占用。
- 构建集中式日志管理(如 ELK 或兼容方案),统一收集、检索与告警。
- 结合 systemd/journald 与 rsyslog/syslog 的能力,统一系统与应用日志链路与权限模型。
二 日志库与级别配置
- 库选型:优先 Winston、Pino、Bunyan 等成熟库,具备多目标输出、级别控制与格式化能力;高并发场景可优先 Pino 的低开销特性。
- 级别策略:开发环境可用 DEBUG/INFO,生产环境建议 WARN/ERROR 为主,必要时通过环境变量动态调节。
- 异步与非阻塞:启用异步传输/批量写入,避免同步 I/O 影响请求延迟。
- 结构化与上下文:统一使用 JSON,附带 timestamp、level、service、trace_id 等关键字段,便于聚合与追踪。
- 异常与未捕获事件:注册 uncaughtException、unhandledRejection 并记录关键上下文后安全退出,防止日志丢失。
三 本地存储与轮换方案
- 应用内轮换(库自带):如 winston-daily-rotate-file,可按天或按大小切分,便于按时间窗口保留与压缩。
- 系统级轮换(推荐):使用 logrotate 管理 Node.js 日志文件,示例配置(/etc/logrotate.d/nodejs):
- 路径与策略:对 /var/log/myapp/*.log 执行 daily 轮换、rotate 7(保留 7 天)、compress(压缩)、missingok、notifempty、create 0640 root adm。
- 测试与生效:执行 logrotate -d /etc/logrotate.d/nodejs(语法检查),logrotate -f /etc/logrotate.d/nodejs(强制执行一次)。
- 运行方式配合:
- 若使用 PM2,可配置 error_file/out_file 分别写入错误与标准输出,并通过 pm2 logs 统一查看。
- 若以 systemd 服务运行,使用 journalctl -u 服务名 查看服务日志,并与应用日志并行归档。
四 集中式日志与系统日志集成
- 集中式方案:将日志发送至 ELK Stack(Elasticsearch、Logstash、Kibana) 或兼容系统,实现统一索引、检索、可视化与告警。
- 系统日志通道:通过 rsyslog/syslog 将应用日志写入 /var/log/(如 local0),在 /etc/rsyslog.conf 或新增配置中定义目标与格式,便于与系统日志统一权限与留存策略。
- 结构化传输:保持 JSON 输出,便于 Logstash/Elasticsearch 解析与字段化检索。
五 目录权限与运维命令清单
- 目录与权限:日志目录建议 /var/log/myapp,权限 0755,日志文件 0640,属主 root:adm,与系统日志一致的安全模型。
- 常用命令:
- 查看 systemd 服务日志:journalctl -u myapp.service;按时间过滤:journalctl --since “2025-01-01” --until “2025-12-31”。
- 查看 rsyslog 系统日志:tail -f /var/log/syslog。
- 轮转测试与强制执行:logrotate -d /etc/logrotate.d/nodejs、logrotate -f /etc/logrotate.d/nodejs。
- PM2 日志:pm2 logs myapp(区分 out.log/err.log)。
- 容量与清理:通过 rotate 与 compress 控制保留周期;对历史归档可结合 find … -mtime +N -delete 做二次清理(谨慎操作)。