利用日志优化 Ubuntu 上 Node.js 性能的可落地方案
一 日志采集与结构化埋点
// 使用 Pino(高性能)
const pino = require('pino')();
const logger = pino({ level: process.env.LOG_LEVEL || 'info' });
// 中间件:记录请求耗时与响应状态
app.use((req, res, next) => {
const start = process.hrtime.bigint();
const rid = req.headers['x-request-id'] || crypto.randomUUID();
req.requestId = rid;
res.setHeader('x-request-id', rid);
res.on('finish', () => {
const end = process.hrtime.bigint();
const durationMs = Number(end - start) / 1e6;
logger.info({
event: 'http_request', requestId: rid, method: req.method, url: req.url,
statusCode: res.statusCode, durationMs, ip: req.ip, userAgent: req.headers['user-agent']
});
});
next();
});
以上做法可确保日志“可机器读、可聚合、可追溯”,为后续分析打基础。二 日志轮转与保留策略
const DailyRotateFile = require('winston-daily-rotate-file');
const transport = new DailyRotateFile({
filename: 'app-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d'
});
/var/log/nodejs/*.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
systemctl reload my-node-app.service >/dev/null 2>&1 || true
endscript
}
三 日志解析与可视化分析
# 统计错误数
grep -c "ERROR" /var/log/nodejs/combined.log
# 某时段日志
awk '/2025-06-01 10:00:00/,/2025-06-01 11:00:00/' /var/log/nodejs/combined.log
# 响应时间 P95(假设日志含 durationMs 字段)
awk -F'"durationMs":' '{print $2}' /var/log/nodejs/combined.log \
| cut -d',' -f1 | sort -n | awk '{a[NR]=$1} END{print "P95:",a[int(NR*0.95)]}'
四 从日志洞察到性能优化
五 监控告警与持续迭代