Ubuntu 上 Node.js 日志与监控工具的集成方案
一 架构与选型
- 日志采集与输出
- 应用内使用结构化日志库(如 Winston、Pino、Bunyan),统一输出为 JSON,便于检索与分析;开发环境可开启美化输出,生产环境建议仅输出到 stdout/stderr 或按级别分流到文件。结合 PM2 统一托管进程与日志流,便于集中查看与采集。
- 传输与存储
- 小规模或云托管:直接发送到日志服务(如 Datadog、Loggly、New Relic)或错误追踪(如 Sentry)。
- 自建平台:使用 rsyslog/syslog-ng → Logstash → Elasticsearch → Kibana(ELK) 或 Graylog 做集中化存储、解析与可视化。
- 指标与告警
- 通过 prom-client 暴露 /metrics,由 Prometheus 抓取并在 Grafana 展示与告警;日志侧用 Logstash/Graylog 规则或 Kibana 查询实现错误与性能异常告警。
二 快速落地步骤
- 步骤 1 应用内结构化日志
- 以 Winston 为例,输出 JSON 并区分 error 与 combined 两类日志;开发环境加控制台美化,生产环境以 JSON 为主,便于下游解析。
- 步骤 2 运行与采集
- 使用 PM2 启动应用,统一日志到 stdout/stderr;如需文件,配合 winston-daily-rotate-file 做按日切分,避免单文件过大。
- 步骤 3 系统级采集与轮转
- 将应用日志写入 /var/log/nodejs/,用 rsyslog/syslog-ng 或 Filebeat 采集;用 logrotate 做按日轮转、压缩与保留策略,防止磁盘被占满。
- 步骤 4 集中化与可视化
- 自建:部署 ELK/Graylog,配置解析规则(如 grok/JSON 解析器),在 Kibana/Graylog 建立索引模式、仪表盘与告警规则。
- 托管:在 Datadog/Loggly/New Relic 控制台创建日志源与解析管道,完成索引与告警配置。
- 步骤 5 错误追踪
- 集成 Sentry,在应用入口初始化 DSN,对未捕获异常与手动捕获异常进行上报,结合上下文与堆栈定位问题。
- 步骤 6 指标与链路
- 用 prom-client 定义 Histogram 等指标,暴露 /metrics;Prometheus 抓取后在 Grafana 建立服务与接口性能面板,设置阈值告警。
三 示例配置
- 结构化日志与按日轮转(Winston)
- 安装依赖:npm i winston winston-daily-rotate-file
- 代码示例:
- const winston = require(‘winston’);
const DailyRotateFile = require(‘winston-daily-rotate-file’);
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || ‘info’,
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.Console({ format: winston.format.simple() }),
new DailyRotateFile({
filename: ‘/var/log/nodejs/error-%DATE%.log’,
datePattern: ‘YYYY-MM-DD’,
level: ‘error’,
maxFiles: ‘7d’
}),
new DailyRotateFile({
filename: ‘/var/log/nodejs/combined-%DATE%.log’,
datePattern: ‘YYYY-MM-DD’,
maxFiles: ‘14d’
})
]
});
module.exports = logger;
- 系统日志轮转(logrotate)
- 新建 /etc/logrotate.d/nodejs:
- /var/log/nodejs/*.log {
daily
missingok
rotate 7
compress
notifempty
create 0640 root adm
}
- 错误追踪(Sentry)
- 安装:npm i @sentry/node
- 入口初始化(app.js):
- const Sentry = require(‘@sentry/node’);
Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV });
- 指标与暴露(prom-client)
- 安装:npm i prom-client
- 代码示例:
- const client = require(‘prom-client’);
const http = require(‘http’);
const register = client.register;
const httpRequestDurationMs = new client.Histogram({
name: ‘http_request_duration_ms’,
help: ‘Duration of HTTP requests in ms’,
labelNames: [‘method’, ‘route’, ‘code’],
buckets: [5, 15, 50, 100, 200, 300, 400, 500]
});
const server = http.createServer((req, res) => {
const start = Date.now();
res.on(‘finish’, () => {
httpRequestDurationMs
.labels(req.method, req.route?.path || req.url, res.statusCode)
.observe(Date.now() - start);
});
res.end(‘OK’);
});
server.listen(3000, () => console.log(‘Server on :3000, /metrics ready’));
四 运维与最佳实践
- 统一输出与级别控制:生产环境优先 JSON + 合理日志级别(info/warn/error),通过环境变量(如 LOG_LEVEL)动态调整,避免过量日志影响性能与成本。
- 结构化与可观测性:始终输出可解析的 timestamp、level、service、trace_id 等关键字段,便于 ELK/Kibana 或托管服务做聚合、筛选与链路追踪。
- 性能与可靠性:采用异步日志与批量写入,避免阻塞主线程;为文件日志配置 按日轮转与压缩,并监控磁盘使用率。
- 安全与合规:避免记录 敏感信息(密码、密钥、PII);对日志进行 最小权限访问控制 与 传输加密(TLS);集中平台开启 审计与保留策略。
- 告警策略:在 Kibana/Graylog 或托管平台配置基于错误关键字、5xx 比例、P95/P99 延迟的告警;在 Prometheus/Grafana 配置阈值与通知渠道(如 邮件、Slack、Webhook)。