阅读量:4
Ubuntu 下基于日志的 Node.js 性能监控实战
一 日志与指标打点
- 使用结构化日志库输出关键性能字段:选择 Winston 或 Pino,以 JSON 格式记录,便于检索与聚合。示例要点:为每条请求输出 method、url、status、responseTimeMs、route、traceId 等字段,错误日志单独输出并携带 stack。
- 在 Express 中记录响应时间:使用 morgan 的响应时间标记或自定义中间件,在 res.finish 时计算耗时并写入日志;对关键业务片段使用 console.time / console.timeEnd 或 process.hrtime 做细粒度埋点。
- 采集运行时资源指标:在定时任务中记录 process.memoryUsage()、process.cpuUsage(),必要时补充 event loop lag 等自定义指标,用于关联日志定位瓶颈。
- 日志轮转与保留:避免单文件过大,使用 winston-daily-rotate-file 或在系统层面配置 logrotate,按 日/周 轮转并压缩归档,保留 7–30 天 便于回溯。
二 实时查看与命令行分析
- 实时查看:开发/排障时用 tail -f 跟踪日志;系统服务日志用 journalctl -u your-app.service -f;多实例集中查看可用 PM2 logs。
- 快速检索与统计:用 grep 过滤错误与慢请求,用 awk 做聚合统计,如按路由统计平均耗时、P95/P99、Top N 慢路径、错误率等。示例:统计某路由平均响应时间、按状态码分布、按内存字段找峰值。
- 建议做法:将常用分析命令写成 Shell/Node 脚本,固化阈值与输出格式,便于值班与告警联动。
三 指标化与可视化
- 指标暴露:在应用内集成 prom-client,定义 Histogram 记录 HTTP 请求时延,暴露 /metrics 端点供 Prometheus 抓取;按需增加 Gauge 记录内存、CPU、事件循环延迟等。
- 可视化与告警:用 Grafana 构建仪表盘,展示 请求率、P50/P95/P99、错误率、内存 RSS/堆、CPU 使用率 等;在 Prometheus 配置告警规则(如 P95 超过阈值、5xx 突增、内存持续增长)。
- 进程与应用双视角:用 PM2 的 monit 与内置监控查看进程级 CPU/内存,与日志/指标联动排查,形成“进程—应用—业务”的三层可观测性。
四 深度诊断与 APM
- 交互式调试:使用 node --inspect 配合 Chrome DevTools 做 CPU/内存热点定位;对生产问题可先短暂采样,避免长时停机。
- 生产级 APM:接入 New Relic / Datadog 等 APM,获得 调用链追踪、数据库/外部依赖耗时、错误堆栈聚合、部署前后对比 等能力,与日志字段(如 traceId)关联,实现端到端可观测。
- 系统级瓶颈排查:结合 top/htop、vmstat、iostat、free、df 等工具,甄别 CPU 饱和、内存不足、I/O 阻塞 等系统层问题,避免只盯应用日志造成误判。
五 落地配置示例
- 结构化日志与中间件(Express + Winston + 响应时间)
// 安装:npm i winston morgan
const express = require('express');
const winston = require('winston');
const morgan = require('morgan');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
new winston.transports.File({ filename: 'logs/combined.log' })
]
});
const app = express();
app.use(morgan('combined')); // 可替换为 JSON 格式
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
logger.info({
event: 'http_request',
method: req.method,
url: req.url,
status: res.statusCode,
responseTimeMs: duration,
route: req.route?.path || 'unknown',
userAgent: req.get('user-agent'),
traceId: req.headers['x-request-id'] || '-'
});
});
next();
});
app.get('/health', (req, res) => res.json({ status: 'ok' }));
app.listen(3000, () => logger.info({ event: 'server_start', port: 3000 }));
- Prometheus 指标端点(prom-client)
// 安装:npm i prom-client
const client = require('prom-client');
const httpRequestDuration = new client.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status']
});
app.use((req, res, next) => {
const end = httpRequestDuration.startTimer();
res.on('finish', () => {
end({ method: req.method, route: req.route?.path || 'unknown', status: res.statusCode });
});
next();
});
app.get('/metrics', async (req, res) => {
res.set('Content-Type', client.register.contentType);
res.end(await client.register.metrics());
});
- 常用分析命令
# 实时查看
tail -f logs/combined.log
journalctl -u node-app.service -f
# Top N 慢请求(按响应时间字段 responseTimeMs 降序)
awk '$NF ~ /ms/ {gsub("ms","",$NF); dur[$7] += $NF; cnt[$7]++}
END {for (r in dur) printf "%.2fms\t%s\t%d\n", dur[r]/cnt[r], r, cnt[r] | "sort -nr | head"' logs/combined.log
# 5xx 错误率(按分钟)
awk '$9 ~ /^5/ {ts=int($1" "$2); m=ts/60; err[m]++; total[m]++}
END {for (t in total) printf "%s\t%.2f%%\n", strftime("%H:%M",t*60), err[t]/total[t]*100}' logs/combined.log
- 日志轮转(系统级 logrotate,/etc/logrotate.d/nodejs)
/path/to/your/nodejs/logs/*.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
systemctl reload node-app.service >/dev/null 2>&1 || true
endscript
}
以上就是关于“Ubuntu Node.js日志如何进行性能监控”的相关介绍,筋斗云是国内较早的云主机应用的服务商,拥有10余年行业经验,提供丰富的云服务器、租用服务器等相关产品服务。云服务器资源弹性伸缩,主机vCPU、内存性能强悍、超高I/O速度、故障秒级恢复;电子化备案,提交快速,专业团队7×24小时服务支持!
简单好用、高性价比云服务器租用链接:https://www.jindouyun.cn/product/cvm