Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | /**
* 性能监控中间件
* 监控 API 响应时间、慢查询、错误率
*/
interface PerformanceMetrics {
totalRequests: number;
avgResponseTime: number;
slowRequests: number;
errors: number;
endpoints: Record<string, {
count: number;
avgTime: number;
maxTime: number;
errors: number;
}>;
}
const metrics: PerformanceMetrics = {
totalRequests: 0,
avgResponseTime: 0,
slowRequests: 0,
errors: 0,
endpoints: {},
};
const SLOW_THRESHOLD = 1000; // 1 秒视为慢请求
export function performanceMonitor() {
return async (ctx: any, next: any) => {
const start = Date.now();
const endpoint = `${ctx.method} ${ctx.path}`;
// 初始化端点指标
if (!metrics.endpoints[endpoint]) {
metrics.endpoints[endpoint] = {
count: 0,
avgTime: 0,
maxTime: 0,
errors: 0,
};
}
try {
await next();
const duration = Date.now() - start;
// 更新指标
metrics.totalRequests++;
metrics.avgResponseTime =
(metrics.avgResponseTime * (metrics.totalRequests - 1) + duration) / metrics.totalRequests;
const epMetrics = metrics.endpoints[endpoint];
epMetrics.count++;
epMetrics.avgTime = (epMetrics.avgTime * (epMetrics.count - 1) + duration) / epMetrics.count;
epMetrics.maxTime = Math.max(epMetrics.maxTime, duration);
// 慢请求日志
if (duration > SLOW_THRESHOLD) {
metrics.slowRequests++;
console.warn(`[Performance] 慢请求: ${endpoint} - ${duration}ms`);
}
// 添加响应头
ctx.set('X-Response-Time', `${duration}ms`);
} catch (error) {
metrics.errors++;
if (metrics.endpoints[endpoint]) {
metrics.endpoints[endpoint].errors++;
}
throw error;
}
};
}
/**
* 获取性能指标
*/
export function getPerformanceMetrics(): PerformanceMetrics {
return { ...metrics };
}
/**
* 重置性能指标
*/
export function resetPerformanceMetrics(): void {
metrics.totalRequests = 0;
metrics.avgResponseTime = 0;
metrics.slowRequests = 0;
metrics.errors = 0;
metrics.endpoints = {};
}
/**
* 性能指标路由
*/
export async function getMetrics(ctx: any) {
ctx.body = {
code: 0,
data: {
...metrics,
errorRate: metrics.totalRequests > 0
? ((metrics.errors / metrics.totalRequests) * 100).toFixed(2) + '%'
: '0%',
},
};
}
|