Ubuntu Node.js 日志与系统日志的关联方案
一、总体思路
- 让 Node.js 日志进入系统日志通道(如 rsyslog/journald),统一由 journalctl 查询;或在应用内使用结构化日志,通过 Logstash/Filebeat 送入 ELK/Graylog 集中管理。
- 统一字段与标识:为 Node.js 日志添加稳定的 app_name / service / hostname / pid / request_id 等字段,便于与系统日志关联检索与聚合。
- 统一时间:确保 Node.js 使用 UTC 或明确的 时区,与系统时间保持一致,避免跨时区排序错乱。
二、方案一 直连系统日志 rsyslog journald(最小改动)
- 配置系统日志
- 确认 rsyslog 运行并写入 /var/log/syslog:检查并确保配置包含如:*.info;mail.none;authpriv.none;cron.none /var/log/syslog,然后重启服务:sudo systemctl restart rsyslog。
- 在 Node.js 中发送日志到 syslog
- 使用 winston + syslog 传输(示例):
- 安装:npm i winston winston-syslog
- 配置:
- const winston = require(‘winston’);
const SyslogTransport = require(‘winston-syslog’).SyslogTransport;
const logger = winston.createLogger({
level: ‘info’,
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new SyslogTransport({
host: ‘localhost’,
port: 514,
protocol: ‘udp’, // 或 tcp
facility: ‘local0’,
app_name: ‘my-node-app’,
tag: ‘nodejs’
})
]
});
logger.info(‘Application started’, { pid: process.pid, env: process.env.NODE_ENV });
- 查询与关联
- 查看应用日志:journalctl -u my-node-app -t nodejs -f
- 与系统日志联查:journalctl --since “2025-11-28 00:00:00” | grep -E “my-node-app|nodejs|PM2|nginx”
- 按时间窗口排查:journalctl -u my-node-app -S “2025-11-28 10:00:00” -U “2025-11-28 10:05:00”
- 说明
- 若使用 PM2,也可通过内置日志与 systemd 服务配合,或在 PM2 配置中启用 syslog 插件,再用 journalctl 统一检索。
三、方案二 进程内落盘 + systemd 归集(便于文件与系统双通道)
- 使用 winston + DailyRotateFile 输出结构化日志到文件(便于保留与归档):
- 安装:npm i winston winston-daily-rotate-file
- 配置:
- const DailyRotateFile = require(‘winston-daily-rotate-file’);
const logger = winston.createLogger({
level: ‘info’,
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new DailyRotateFile({
filename: ‘logs/error-%DATE%.log’,
datePattern: ‘YYYY-MM-DD’,
level: ‘error’,
maxSize: ‘100m’,
maxFiles: ‘14d’
}),
new DailyRotateFile({
filename: ‘logs/combined-%DATE%.log’,
datePattern: ‘YYYY-MM-DD’,
maxSize: ‘100m’,
maxFiles: ‘14d’
})
]
});
- 用 systemd 归集标准输出/错误到 journald
- 示例服务 /etc/systemd/system/nodeapp.service:
- [Unit]
Description=Node.js App
After=network.target
- [Service]
Type=simple
ExecStart=/usr/bin/node /opt/myapp/app.js
StandardOutput=journal
StandardError=journal
SyslogIdentifier=my-node-app
Environment=NODE_ENV=production
- [Install]
WantedBy=multi-user.target
- 启用与查看:
- sudo systemctl daemon-reload && sudo systemctl enable --now nodeapp
- journalctl -u nodeapp -f
- 关联查询
- 系统层:journalctl -u nodeapp -o json-pretty | jq ‘select(.SYSLOG_IDENTIFIER==“my-node-app”)’
- 应用层:tail -f logs/combined-$(date +%F).log | jq ‘select(.level==“error”)’
四、方案三 集中式日志平台 ELK 或 Graylog(跨主机统一检索与告警)
- 架构建议
- 应用 → Filebeat/Logstash → Elasticsearch → Kibana/Graylog
- 快速落地(Logstash 接收 syslog)
- 安装 Logstash 后配置 /etc/logstash/conf.d/nodejs.conf:
- input { syslog { port => 514 type => “nodejs” } }
- filter { if [type] == “nodejs” { json { source => “message” } } }
- output { elasticsearch { hosts => [“localhost:9200”] index => “nodejs-%{+YYYY.MM.dd}” } }
- 启动 Logstash:sudo systemctl start logstash
- Kibana 创建索引模式:nodejs-*
- 关联方式
- 在 Node.js 日志中加入 host / service / trace_id,与系统日志字段(如 _HOSTNAME / SYSLOG_IDENTIFIER)一致,便于在 Kibana/Graylog 中联动过滤与下钻。
五、关联与排障的最佳实践
- 统一字段与格式
- 建议统一使用 JSON 日志,包含:timestamp、level、msg、app、service、hostname、pid、req_id、trace_id、user_id 等;系统日志侧使用 SYSLOG_IDENTIFIER / _HOSTNAME 等字段对齐。
- 时间与时区
- Node.js 建议统一 process.env.TZ 或日志库时间格式,避免与系统时间不一致导致排序错乱。
- 日志轮转与保留
- 文件日志用 winston-daily-rotate-file 或 logrotate 管理;系统日志由 rsyslog/journald 策略管理,避免磁盘被占满。
- 快速检索命令示例
- 按服务与级别:journalctl -u nodeapp -t nodejs -p err -b
- 跨日志关联:journalctl --since “2025-11-28 09:00” | grep -E “my-node-app|PM2|OOM”
- 结构化检索:tail -f logs/combined-*.log | jq ‘select(.level==“error” and .service==“payment”)’
- 监控与告警
- 结合 Prometheus + Grafana 做指标与日志联动告警;或在 ELK/Graylog 中配置阈值与通知规则。