1. 启用结构化详细日志记录
在Ubuntu环境下,使用高性能日志库(如Winston或Pino)配置结构化日志,确保记录关键性能指标(请求时间、响应状态、错误详情、内存/CPU使用率)。例如,用Winston记录JSON格式日志:
const winston = require('winston');
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' })
]
});
logger.info('Request received', { method: 'GET', url: '/api/data', responseTime: 120 });
结构化日志便于后续用工具(如ELK、Grafana)解析和分析。
2. 内置性能工具集成
利用Node.js内置模块收集性能数据并写入日志:
process.memoryUsage():记录内存使用情况(heapUsed、rss等);process.hrtime():高精度计时代码段执行时间(纳秒级);perf_hooks:更详细的性能监控(如CPU时间、事件循环延迟)。const { performance, PerformanceObserver } = require('perf_hooks');
const start = performance.now();
// 模拟业务代码
setTimeout(() => {
const end = performance.now();
logger.info('API execution time', { time: end - start });
}, 100);
// 监控内存使用
setInterval(() => {
const memory = process.memoryUsage();
logger.info('Memory usage', memory);
}, 5000);
这些数据能直接反映应用的资源消耗情况。
3. 第三方APM工具接入
使用New Relic、Datadog或Elastic APM等APM工具,自动收集性能指标(请求延迟、数据库查询时间、错误率)并生成可视化报告。以PM2为例(轻量级进程管理器):
npm install pm2 -g
pm2 start app.js --name "my-node-app"
pm2 monit # 实时监控CPU、内存、日志
pm2 logs # 查看实时日志
APM工具能快速定位性能瓶颈(如慢查询、高延迟接口),无需手动解析日志。
4. 日志分析与瓶颈识别
使用工具分析日志中的性能数据:
grep筛选错误日志(grep "ERROR" combined.log)、awk统计平均响应时间(awk '{sum += $NF} END {print "Average:", sum/NR}' combined.log);combined.log中的responseTime字段,识别慢接口。5. 性能分析工具深度诊断
对于复杂瓶颈(如CPU热点、内存泄漏),使用Node.js内置工具:
node --inspect:启动调试模式,用Chrome DevTools分析CPU profile(生成火焰图,查看耗时函数);node --prof:生成性能分析文件(isolate-*.log),用node --prof-process解析(查看函数调用栈和时间占比);heapdump:生成堆快照(require('heapdump').writeSnapshot()),分析内存泄漏(如未释放的对象)。node --inspect app.js # 打开Chrome://inspect,录制CPU profile
node --prof app.js # 运行10分钟后,生成profile文件
node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt
这些工具能深入代码层面,定位具体性能问题。
6. 日志轮转与长期管理
避免日志文件过大占用磁盘空间,使用**winston-daily-rotate-file或logrotate**进行日志轮转:
const DailyRotateFile = require('winston-daily-rotate-file');
const logger = winston.createLogger({
transports: [
new DailyRotateFile({
filename: 'logs/application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d'
})
]
});
/etc/logrotate.d/nodejs):/path/to/logs/*.log {
daily
rotate 14
compress
missingok
notifempty
create 0640 www-data www-data
}
日志轮转能保持日志文件的可管理性,便于长期分析。