Ubuntu 下用日志做 Node.js 性能监控的实操方案
一 日志采集与结构化
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
// 在请求入口记录关键指标
const start = process.hrtime.bigint();
// ... 处理请求
const diffMs = Number(process.hrtime.bigint() - start) / 1e6;
logger.info('http_request', {
method: 'GET', url: '/api', status: 200,
duration_ms: diffMs,
memory_rss_mb: Math.round(process.memoryUsage().rss / 1024 / 1024)
});
/var/log/nodejs/*.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
}
二 在日志中埋点与输出关键指标
logger.info('runtime_metrics', {
memory_rss_mb, heap_used_mb: mu.heapUsed/1024/1024,
heap_total_mb: mu.heapTotal/1024/1024,
cpu_user_ms: cu.user/1000, cpu_sys_ms: cu.system/1000,
event_loop_lag_ms: lag
});
三 日志解析与趋势分析
grep "ERROR" combined.log | wc -lawk '/2025-04-01 00:00:00/,/2025-04-01 23:59:59/' combined.log# Top URL
awk '$7 ~ /http_request/ {print $9}' combined.log | sort | uniq -c | sort -nr | head
# 近似 P95(ms)
awk '$7 ~ /http_request/ {print $11}' combined.log | sort -n | awk 'BEGIN{c=0} {a[c++]=$1} END{print a[int(c*0.95)]}'
四 可视化与告警
五 快速落地与进阶
pm2 start app.js --name my-app、pm2 monit、pm2 logs my-app,获得进程级 CPU/内存 与日志聚合;node --prof-process 分析);