Node.js应用的性能调优是一个系统性的工作,而日志分析是其中至关重要的环节。以下是利用Node.js日志进行性能调优的详细方法:
const winston = require('winston');
const logger = winston.createLogger({
levels: winston.config.syslog.levels,
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'combined.log' })
]
});
info
级别,开发环境使用debug
winston
、pino
或bunyan
等专业日志库// 记录请求处理时间
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
logger.info(`Request ${req.method} ${req.url} took ${duration}ms`);
if (duration > 500) { // 设置慢请求阈值
logger.warn(`Slow request detected: ${req.method} ${req.url} (${duration}ms)`);
}
});
next();
});
// 定期记录内存使用情况
setInterval(() => {
const memoryUsage = process.memoryUsage();
logger.debug('Memory usage:', {
rss: `${(memoryUsage.rss / 1024 / 1024).toFixed(2)} MB`,
heapTotal: `${(memoryUsage.heapTotal / 1024 / 1024).toFixed(2)} MB`,
heapUsed: `${(memoryUsage.heapUsed / 1024 / 1024).toFixed(2)} MB`,
external: `${(memoryUsage.external / 1024 / 1024).toFixed(2)} MB`
});
}, 60000); // 每分钟记录一次
// 监控事件循环延迟
const eventLoopLag = require('event-loop-lag');
const lag = eventLoopLag(1000); // 1秒采样间隔
setInterval(() => {
const delay = lag();
logger.debug(`Event loop lag: ${delay.toFixed(2)}ms`);
if (delay > 50) { // 设置阈值
logger.warn(`High event loop lag detected: ${delay.toFixed(2)}ms`);
}
}, 5000);
// 使用Mongoose示例
mongoose.set('debug', (collectionName, method, query, doc) => {
logger.debug(`Mongoose: ${collectionName}.${method}`, {
query: JSON.stringify(query),
doc: doc
});
});
process.on('uncaughtException', (err) => {
logger.error('Uncaught Exception:', {
message: err.message,
stack: err.stack,
timestamp: new Date().toISOString()
});
// 根据情况决定是否退出进程
});
process.on('unhandledRejection', (reason, promise) => {
logger.error('Unhandled Rejection at:', {
promise: promise,
reason: reason,
timestamp: new Date().toISOString()
});
});
ELK Stack (Elasticsearch, Logstash, Kibana)
Grafana + Prometheus
AWS CloudWatch / Google Stackdriver
识别瓶颈:
优化建议:
AB测试验证:
结构化日志:
logger.info('Request processed', {
method: req.method,
path: req.path,
status: res.statusCode,
duration: duration,
userAgent: req.headers['user-agent'],
userId: req.user?.id
});
采样日志:
日志轮转:
winston-daily-rotate-file
等工具自动轮转日志文件通过系统性地收集、分析和响应Node.js应用日志中的性能指标,您可以有效地识别和解决性能瓶颈,提升应用的整体表现。