168 lines
4.0 KiB
JavaScript
168 lines
4.0 KiB
JavaScript
const logger = require("./logger");
|
||
|
||
/**
|
||
* 性能监控工具
|
||
*/
|
||
class PerformanceMonitor {
|
||
constructor() {
|
||
this.requestCount = 0;
|
||
this.activeRequests = 0;
|
||
this.maxActiveRequests = 0;
|
||
this.errorCount = 0;
|
||
this.startTime = Date.now();
|
||
this.responseTimeHistory = [];
|
||
this.errorHistory = [];
|
||
}
|
||
|
||
/**
|
||
* 记录请求开始
|
||
*/
|
||
requestStart(req) {
|
||
this.requestCount++;
|
||
this.activeRequests++;
|
||
|
||
if (this.activeRequests > this.maxActiveRequests) {
|
||
this.maxActiveRequests = this.activeRequests;
|
||
}
|
||
|
||
// 记录请求开始时间
|
||
req.startTime = Date.now();
|
||
|
||
// 如果并发请求过多,记录警告
|
||
if (this.activeRequests > 100) {
|
||
logger.warn(`高并发警告: 当前活跃请求数 ${this.activeRequests}`);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 记录请求结束
|
||
*/
|
||
requestEnd(req, res) {
|
||
this.activeRequests--;
|
||
|
||
if (req.startTime) {
|
||
const responseTime = Date.now() - req.startTime;
|
||
this.responseTimeHistory.push(responseTime);
|
||
|
||
// 只保留最近1000条记录
|
||
if (this.responseTimeHistory.length > 1000) {
|
||
this.responseTimeHistory.shift();
|
||
}
|
||
|
||
// 如果响应时间过长,记录警告
|
||
if (responseTime > 10000) { // 10秒
|
||
logger.warn(`响应时间过长: ${responseTime}ms, URL: ${req.url}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 记录错误
|
||
*/
|
||
recordError(error, req) {
|
||
this.errorCount++;
|
||
this.errorHistory.push({
|
||
timestamp: Date.now(),
|
||
error: error.message,
|
||
url: req ? req.url : 'unknown',
|
||
method: req ? req.method : 'unknown'
|
||
});
|
||
|
||
// 只保留最近100条错误记录
|
||
if (this.errorHistory.length > 100) {
|
||
this.errorHistory.shift();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取性能统计
|
||
*/
|
||
getStats() {
|
||
const uptime = Date.now() - this.startTime;
|
||
const avgResponseTime = this.responseTimeHistory.length > 0
|
||
? this.responseTimeHistory.reduce((a, b) => a + b, 0) / this.responseTimeHistory.length
|
||
: 0;
|
||
|
||
return {
|
||
uptime: Math.floor(uptime / 1000), // 秒
|
||
totalRequests: this.requestCount,
|
||
activeRequests: this.activeRequests,
|
||
maxActiveRequests: this.maxActiveRequests,
|
||
errorCount: this.errorCount,
|
||
errorRate: this.requestCount > 0 ? (this.errorCount / this.requestCount * 100).toFixed(2) : 0,
|
||
avgResponseTime: Math.floor(avgResponseTime),
|
||
requestsPerSecond: this.requestCount > 0 ? (this.requestCount / (uptime / 1000)).toFixed(2) : 0,
|
||
recentErrors: this.errorHistory.slice(-5) // 最近5个错误
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 重置统计
|
||
*/
|
||
reset() {
|
||
this.requestCount = 0;
|
||
this.activeRequests = 0;
|
||
this.maxActiveRequests = 0;
|
||
this.errorCount = 0;
|
||
this.startTime = Date.now();
|
||
this.responseTimeHistory = [];
|
||
this.errorHistory = [];
|
||
}
|
||
|
||
/**
|
||
* 定期报告性能状态
|
||
*/
|
||
startPeriodicReport(intervalMs = 60000) { // 默认每分钟报告一次
|
||
setInterval(() => {
|
||
const stats = this.getStats();
|
||
logger.info("性能统计:", stats);
|
||
|
||
// 如果错误率过高,发出警告
|
||
if (stats.errorRate > 5) {
|
||
logger.warn(`错误率过高: ${stats.errorRate}%`);
|
||
}
|
||
|
||
// 如果平均响应时间过长,发出警告
|
||
if (stats.avgResponseTime > 5000) {
|
||
logger.warn(`平均响应时间过长: ${stats.avgResponseTime}ms`);
|
||
}
|
||
}, intervalMs);
|
||
}
|
||
}
|
||
|
||
// 创建全局监控实例
|
||
const monitor = new PerformanceMonitor();
|
||
|
||
/**
|
||
* Express中间件:监控请求
|
||
*/
|
||
function monitoringMiddleware(req, res, next) {
|
||
monitor.requestStart(req);
|
||
|
||
// 监听响应结束事件
|
||
res.on('finish', () => {
|
||
monitor.requestEnd(req, res);
|
||
});
|
||
|
||
// 监听响应关闭事件(客户端断开连接)
|
||
res.on('close', () => {
|
||
monitor.requestEnd(req, res);
|
||
});
|
||
|
||
next();
|
||
}
|
||
|
||
/**
|
||
* 错误监控中间件
|
||
*/
|
||
function errorMonitoringMiddleware(err, req, res, next) {
|
||
monitor.recordError(err, req);
|
||
next(err);
|
||
}
|
||
|
||
module.exports = {
|
||
PerformanceMonitor,
|
||
monitor,
|
||
monitoringMiddleware,
|
||
errorMonitoringMiddleware
|
||
};
|