import { logger } from "./logger"; export interface PerformanceMetric { name: string; duration: number; timestamp: number; metadata?: Record; } class PerformanceMonitor { private metrics: PerformanceMetric[] = []; private maxMetrics = 1000; /** * 测量函数执行时间 */ async measure( name: string, fn: () => Promise, metadata?: Record ): Promise { const startTime = Date.now(); try { const result = await fn(); const duration = Date.now() - startTime; this.recordMetric(name, duration, metadata); return result; } catch (error) { const duration = Date.now() - startTime; this.recordMetric(`${name}_error`, duration, { ...metadata, error: true, }); throw error; } } /** * 同步测量函数执行时间 */ measureSync( name: string, fn: () => T, metadata?: Record ): T { const startTime = Date.now(); try { const result = fn(); const duration = Date.now() - startTime; this.recordMetric(name, duration, metadata); return result; } catch (error) { const duration = Date.now() - startTime; this.recordMetric(`${name}_error`, duration, { ...metadata, error: true, }); throw error; } } /** * 记录性能指标 */ recordMetric( name: string, duration: number, metadata?: Record ): void { const metric: PerformanceMetric = { name, duration, timestamp: Date.now(), metadata, }; this.metrics.push(metric); // 限制指标数量 if (this.metrics.length > this.maxMetrics) { this.metrics = this.metrics.slice(-this.maxMetrics / 2); } // 记录慢查询 if (duration > 1000) { logger.warn("Slow operation detected", { name, duration, metadata, }); } } /** * 获取性能统计 */ getStats(): { totalMetrics: number; averageDuration: number; slowestOperations: PerformanceMetric[]; fastestOperations: PerformanceMetric[]; operationCounts: Record; } { if (this.metrics.length === 0) { return { totalMetrics: 0, averageDuration: 0, slowestOperations: [], fastestOperations: [], operationCounts: {}, }; } const totalDuration = this.metrics.reduce( (sum, metric) => sum + metric.duration, 0 ); const averageDuration = totalDuration / this.metrics.length; // 按名称分组统计 const operationCounts: Record = {}; this.metrics.forEach((metric) => { operationCounts[metric.name] = (operationCounts[metric.name] || 0) + 1; }); // 获取最慢的操作 const slowestOperations = [...this.metrics] .sort((a, b) => b.duration - a.duration) .slice(0, 10); // 获取最快的操作 const fastestOperations = [...this.metrics] .sort((a, b) => a.duration - b.duration) .slice(0, 10); return { totalMetrics: this.metrics.length, averageDuration, slowestOperations, fastestOperations, operationCounts, }; } /** * 清理旧指标 */ cleanup(maxAge: number = 24 * 60 * 60 * 1000): void { const cutoff = Date.now() - maxAge; this.metrics = this.metrics.filter((metric) => metric.timestamp > cutoff); } /** * 导出性能报告 */ generateReport(): string { const stats = this.getStats(); return ` Performance Report ================== Total Metrics: ${stats.totalMetrics} Average Duration: ${stats.averageDuration.toFixed(2)}ms Slowest Operations: ${stats.slowestOperations .map((op) => ` ${op.name}: ${op.duration}ms`) .join("\n")} Operation Counts: ${Object.entries(stats.operationCounts) .sort(([, a], [, b]) => b - a) .map(([name, count]) => ` ${name}: ${count}`) .join("\n")} `.trim(); } } export const performanceMonitor = new PerformanceMonitor(); // 定期清理旧指标 if (typeof window === "undefined") { setInterval(() => { performanceMonitor.cleanup(); }, 60 * 60 * 1000); // 每小时清理一次 }