监控 Debian 上 Node.js 的日志与性能
一 整体架构与关键指标
- 采集与存储:在应用侧使用结构化日志(如 JSON),通过 Winston/Pino/Bunyan 输出到文件或标准输出;多实例/多机环境建议接入 ELK(Elasticsearch、Logstash、Kibana)/Graylog/Fluentd 做集中化与检索。
- 指标与可视化:暴露 HTTP 指标端点(如 /metrics),用 Prometheus 抓取并在 Grafana 展示;结合日志派生业务与性能指标。
- 进程与系统:用 PM2 管理进程与日志,或用 systemd/journald 统一收集服务日志;系统层面配合 top/htop、vmstat、iostat、free、df 观察资源瓶颈。
- 告警:在 Kibana 或 Prometheus Alertmanager 配置阈值与异常告警,覆盖错误激增、P95/P99 延迟上升、磁盘空间不足等场景。
二 应用侧日志与指标埋点
- 日志库与级别:选择 Winston/Pino/Bunyan,生产环境建议 WARN/ERROR 为主,按需开启 INFO/DEBUG;统一使用 JSON 格式并携带 timestamp、level、service、request_id、user_id 等字段,便于检索与聚合。
- 请求与性能日志:在 HTTP 中间件(如 Express)记录 method、url、status、durationMs、contentLength、userAgent、ip;在关键业务处埋点(如 DB 查询、外部 API 调用)记录 耗时与结果。
- 异步与非阻塞:优先使用异步日志与批量/缓冲传输,避免同步写磁盘阻塞事件循环;高并发场景可结合采样与降级策略。
- 示例(Winston,含 request_id 透传):
// 安装:npm i winston express morgan
const winston = require('winston');
const express = require('express');
const morgan = require('morgan');
const { v4: uuidv4 } = require('uuid');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'app.log' })
]
});
const app = express();
app.use((req, res, next) => {
req.id = req.headers['x-request-id'] || uuidv4();
res.setHeader('X-Request-Id', req.id);
next();
});
app.use(morgan('combined', {
stream: { write: msg => logger.info(msg.trim(), { reqId: req.id }) }
}));
app.get('/ping', (req, res) => {
const start = Date.now();
// ... 业务处理
const durationMs = Date.now() - start;
logger.info('http.request', {
reqId: req.id, method: 'GET', url: '/ping', status: 200, durationMs
});
res.json({ ok: true });
});
app.listen(3000, () => logger.info('Server started', { port: 3000 }));
提示:若使用 PM2,可结合其日志文件与集群日志前缀,便于按实例区分。
三 系统与服务层日志管理
- systemd 与 journald:将应用以 systemd 服务运行,使用 journalctl -u your-app.service -f 实时查看与过滤日志;适合无侵入地收集 stdout/stderr。
- 进程管理:使用 PM2 时,通过 pm2 logs 实时查看与轮转;PM2 也提供基础 CPU/内存 监控与集群管理。
- 日志轮转:
- 应用日志建议用 winston-daily-rotate-file 按天/大小切分;
- 系统服务日志用 logrotate 管理(如 /var/log/yourapp/*.log),控制单文件大小与保留份数,避免磁盘被占满。
- 集中化与聚合:多机部署建议将日志统一发送到 ELK/Graylog/Fluentd,便于检索、可视化与告警。
四 指标监控与可视化
- 指标暴露:在应用中使用 prom-client 暴露 /metrics,采集 HTTP 请求耗时直方图、计数器、Gauge(内存/事件循环延迟) 等;与日志字段(如 request_id)联动,实现“日志→指标”的闭环。
- 抓取与展示:用 Prometheus 抓取 /metrics,在 Grafana 构建仪表盘,关注 请求量、错误率、P50/P95/P99 延迟、吞吐、活跃请求数 等核心面板。
- 日志派生指标:在 Logstash/Elasticsearch 中对日志做聚合(如按 status、route、service 统计计数与分位数),将结果写入 Prometheus 或直接在 Kibana 可视化趋势。
- 告警规则示例(Prometheus):
- 5xx 错误率上升:rate(http_requests_total{status=~“5…”}[1m]) / rate(http_requests_total[1m]) > 0.01
- P95 延迟升高:histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[1m])) by (le)) > 1
五 告警与持续优化
- 告警策略:在 Kibana Alerting 或 Alertmanager 配置规则,覆盖 错误率、延迟阈值、磁盘空间、日志速率异常 等;结合 PagerDuty/企业微信/钉钉 通知。
- 趋势与复盘:定期在 Kibana/Grafana 复盘 错误率、TOP URL、慢查询、依赖可用性 等趋势,定位性能瓶颈与回归问题。
- 安全与合规:对日志链路启用 TLS 传输、最小权限访问;对敏感字段(如 Authorization、password)做脱敏与合规存储。
- 运行与调优:结合 PM2/New Relic/Datadog 与 系统工具(top/htop、vmstat、iostat、free、df) 排查 内存泄漏、CPU 饱和、I/O 瓶颈;必要时使用 node --inspect 或 V8 profiler 做深度分析。