UNPKG

yijing-bazi-mcp

Version:

易经八字分析 MCP 服务器 - 提供传统命理分析和易经卦象解读的AI工具

650 lines (559 loc) 17.4 kB
/** * 性能监控工具类 * 提供性能指标收集、分析和报告功能 */ const os = require('os'); const process = require('process'); const { performance, PerformanceObserver } = require('perf_hooks'); const Logger = require('./logger'); const config = require('../config/config'); const { ErrorHandler } = require('./error-handler'); /** * 性能指标收集器 */ class PerformanceCollector { constructor() { this.logger = new Logger(); this.errorHandler = new ErrorHandler(); this.metrics = new Map(); this.timers = new Map(); this.counters = new Map(); this.histograms = new Map(); this.startTime = Date.now(); this.isMonitoring = false; // 性能观察器 this.observers = new Map(); this.setupPerformanceObservers(); } /** * 设置性能观察器 */ setupPerformanceObservers() { try { // 观察函数调用性能 const functionObserver = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { this.recordMetric('function_duration', entry.name, entry.duration); } }); functionObserver.observe({ entryTypes: ['function'] }); this.observers.set('function', functionObserver); // 观察HTTP请求性能 const httpObserver = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { this.recordMetric('http_duration', entry.name, entry.duration); } }); httpObserver.observe({ entryTypes: ['http'] }); this.observers.set('http', httpObserver); } catch (error) { this.logger.warn('性能观察器设置失败', { error: error.message }); } } /** * 开始监控 */ startMonitoring() { if (this.isMonitoring) return; this.isMonitoring = true; const interval = config.get('performance.monitoring.metricsInterval') || 60000; this.monitoringInterval = setInterval(() => { this.collectSystemMetrics(); this.collectProcessMetrics(); this.collectCustomMetrics(); }, interval); this.logger.info('性能监控已启动', { interval }); } /** * 停止监控 */ stopMonitoring() { if (!this.isMonitoring) return; this.isMonitoring = false; if (this.monitoringInterval) { clearInterval(this.monitoringInterval); } this.logger.info('性能监控已停止'); } /** * 收集系统指标 */ collectSystemMetrics() { try { const cpus = os.cpus(); const loadAvg = os.loadavg(); const totalMem = os.totalmem(); const freeMem = os.freemem(); const usedMem = totalMem - freeMem; this.recordMetric('system', 'cpu_count', cpus.length); this.recordMetric('system', 'load_avg_1m', loadAvg[0]); this.recordMetric('system', 'load_avg_5m', loadAvg[1]); this.recordMetric('system', 'load_avg_15m', loadAvg[2]); this.recordMetric('system', 'memory_total', totalMem); this.recordMetric('system', 'memory_free', freeMem); this.recordMetric('system', 'memory_used', usedMem); this.recordMetric('system', 'memory_usage_percent', (usedMem / totalMem) * 100); // CPU使用率(需要计算差值) this.calculateCPUUsage(); } catch (error) { this.logger.error('系统指标收集错误', { error: error.message }); } } /** * 收集进程指标 */ collectProcessMetrics() { try { const memUsage = process.memoryUsage(); const cpuUsage = process.cpuUsage(); const uptime = process.uptime(); this.recordMetric('process', 'memory_rss', memUsage.rss); this.recordMetric('process', 'memory_heap_total', memUsage.heapTotal); this.recordMetric('process', 'memory_heap_used', memUsage.heapUsed); this.recordMetric('process', 'memory_external', memUsage.external); this.recordMetric('process', 'memory_array_buffers', memUsage.arrayBuffers || 0); this.recordMetric('process', 'cpu_user', cpuUsage.user); this.recordMetric('process', 'cpu_system', cpuUsage.system); this.recordMetric('process', 'uptime', uptime); this.recordMetric('process', 'pid', process.pid); // 堆使用率 const heapUsagePercent = (memUsage.heapUsed / memUsage.heapTotal) * 100; this.recordMetric('process', 'heap_usage_percent', heapUsagePercent); } catch (error) { this.logger.error('进程指标收集错误', { error: error.message }); } } /** * 收集自定义指标 */ collectCustomMetrics() { try { // 收集计数器指标 for (const [name, value] of this.counters.entries()) { this.recordMetric('custom_counter', name, value); } // 收集直方图指标 for (const [name, histogram] of this.histograms.entries()) { const stats = this.calculateHistogramStats(histogram); this.recordMetric('custom_histogram', `${name}_count`, stats.count); this.recordMetric('custom_histogram', `${name}_sum`, stats.sum); this.recordMetric('custom_histogram', `${name}_avg`, stats.avg); this.recordMetric('custom_histogram', `${name}_min`, stats.min); this.recordMetric('custom_histogram', `${name}_max`, stats.max); this.recordMetric('custom_histogram', `${name}_p50`, stats.p50); this.recordMetric('custom_histogram', `${name}_p95`, stats.p95); this.recordMetric('custom_histogram', `${name}_p99`, stats.p99); } } catch (error) { this.logger.error('自定义指标收集错误', { error: error.message }); } } /** * 计算CPU使用率 */ calculateCPUUsage() { const cpus = os.cpus(); let totalIdle = 0; let totalTick = 0; for (const cpu of cpus) { for (const type in cpu.times) { totalTick += cpu.times[type]; } totalIdle += cpu.times.idle; } const idle = totalIdle / cpus.length; const total = totalTick / cpus.length; const usage = 100 - ~~(100 * idle / total); this.recordMetric('system', 'cpu_usage_percent', usage); } /** * 计算直方图统计信息 * @param {Array<number>} values - 数值数组 * @returns {Object} 统计信息 */ calculateHistogramStats(values) { if (values.length === 0) { return { count: 0, sum: 0, avg: 0, min: 0, max: 0, p50: 0, p95: 0, p99: 0 }; } const sorted = [...values].sort((a, b) => a - b); const sum = values.reduce((a, b) => a + b, 0); return { count: values.length, sum, avg: sum / values.length, min: sorted[0], max: sorted[sorted.length - 1], p50: this.percentile(sorted, 0.5), p95: this.percentile(sorted, 0.95), p99: this.percentile(sorted, 0.99) }; } /** * 计算百分位数 * @param {Array<number>} sortedValues - 已排序的数值数组 * @param {number} percentile - 百分位数(0-1) * @returns {number} 百分位数值 */ percentile(sortedValues, percentile) { const index = percentile * (sortedValues.length - 1); const lower = Math.floor(index); const upper = Math.ceil(index); const weight = index % 1; if (upper >= sortedValues.length) { return sortedValues[sortedValues.length - 1]; } return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight; } /** * 记录指标 * @param {string} category - 指标分类 * @param {string} name - 指标名称 * @param {number} value - 指标值 * @param {Object} tags - 标签 */ recordMetric(category, name, value, tags = {}) { const key = `${category}.${name}`; const timestamp = Date.now(); if (!this.metrics.has(key)) { this.metrics.set(key, []); } const metric = { value, timestamp, tags }; this.metrics.get(key).push(metric); // 限制历史数据量 const maxHistory = 1000; const history = this.metrics.get(key); if (history.length > maxHistory) { history.splice(0, history.length - maxHistory); } } /** * 开始计时 * @param {string} name - 计时器名称 * @param {Object} tags - 标签 */ startTimer(name, tags = {}) { const timer = { name, startTime: performance.now(), tags }; this.timers.set(name, timer); return timer; } /** * 结束计时 * @param {string} name - 计时器名称 * @returns {number} 耗时(毫秒) */ endTimer(name) { const timer = this.timers.get(name); if (!timer) { this.logger.warn('计时器不存在', { name }); return 0; } const duration = performance.now() - timer.startTime; this.timers.delete(name); // 记录到直方图 this.addToHistogram(`timer_${name}`, duration); this.recordMetric('timer', name, duration, timer.tags); return duration; } /** * 增加计数器 * @param {string} name - 计数器名称 * @param {number} value - 增加值 */ incrementCounter(name, value = 1) { const current = this.counters.get(name) || 0; this.counters.set(name, current + value); } /** * 设置计数器值 * @param {string} name - 计数器名称 * @param {number} value - 计数器值 */ setCounter(name, value) { this.counters.set(name, value); } /** * 获取计数器值 * @param {string} name - 计数器名称 * @returns {number} 计数器值 */ getCounter(name) { return this.counters.get(name) || 0; } /** * 添加值到直方图 * @param {string} name - 直方图名称 * @param {number} value - 值 */ addToHistogram(name, value) { if (!this.histograms.has(name)) { this.histograms.set(name, []); } const histogram = this.histograms.get(name); histogram.push(value); // 限制直方图大小 const maxSize = 10000; if (histogram.length > maxSize) { histogram.splice(0, histogram.length - maxSize); } } /** * 获取指标数据 * @param {string} key - 指标键 * @param {number} since - 起始时间戳 * @returns {Array} 指标数据 */ getMetrics(key, since = 0) { const metrics = this.metrics.get(key) || []; return metrics.filter(m => m.timestamp >= since); } /** * 获取所有指标键 * @returns {Array<string>} 指标键数组 */ getMetricKeys() { return Array.from(this.metrics.keys()); } /** * 获取性能摘要 * @returns {Object} 性能摘要 */ getPerformanceSummary() { const now = Date.now(); const uptime = now - this.startTime; // 获取最新的系统指标 const getLatestMetric = (key) => { const metrics = this.getMetrics(key); return metrics.length > 0 ? metrics[metrics.length - 1].value : 0; }; return { uptime, timestamp: now, system: { cpuUsage: getLatestMetric('system.cpu_usage_percent'), memoryUsage: getLatestMetric('system.memory_usage_percent'), loadAverage: { '1m': getLatestMetric('system.load_avg_1m'), '5m': getLatestMetric('system.load_avg_5m'), '15m': getLatestMetric('system.load_avg_15m') } }, process: { memoryUsage: { rss: getLatestMetric('process.memory_rss'), heapTotal: getLatestMetric('process.memory_heap_total'), heapUsed: getLatestMetric('process.memory_heap_used'), heapUsagePercent: getLatestMetric('process.heap_usage_percent') }, cpuUsage: { user: getLatestMetric('process.cpu_user'), system: getLatestMetric('process.cpu_system') }, uptime: getLatestMetric('process.uptime') }, counters: Object.fromEntries(this.counters), activeTimers: this.timers.size, totalMetrics: this.metrics.size }; } /** * 获取详细性能报告 * @param {number} timeRange - 时间范围(毫秒) * @returns {Object} 详细报告 */ getDetailedReport(timeRange = 3600000) { // 默认1小时 const since = Date.now() - timeRange; const report = { summary: this.getPerformanceSummary(), metrics: {}, histograms: {}, analysis: {} }; // 收集指标数据 for (const key of this.getMetricKeys()) { const metrics = this.getMetrics(key, since); if (metrics.length > 0) { const values = metrics.map(m => m.value); report.metrics[key] = { count: values.length, latest: values[values.length - 1], stats: this.calculateHistogramStats(values) }; } } // 收集直方图数据 for (const [name, values] of this.histograms.entries()) { report.histograms[name] = this.calculateHistogramStats(values); } // 性能分析 report.analysis = this.analyzePerformance(report); return report; } /** * 分析性能数据 * @param {Object} report - 性能报告 * @returns {Object} 分析结果 */ analyzePerformance(report) { const analysis = { alerts: [], recommendations: [], trends: {}, health: 'good' }; const { system, process } = report.summary; // CPU使用率分析 if (system.cpuUsage > 80) { analysis.alerts.push({ type: 'high_cpu', severity: 'warning', message: `CPU使用率过高: ${system.cpuUsage.toFixed(2)}%` }); analysis.health = 'warning'; } // 内存使用率分析 if (system.memoryUsage > 85) { analysis.alerts.push({ type: 'high_memory', severity: 'warning', message: `内存使用率过高: ${system.memoryUsage.toFixed(2)}%` }); analysis.health = 'warning'; } // 堆内存使用率分析 if (process.memoryUsage.heapUsagePercent > 90) { analysis.alerts.push({ type: 'high_heap', severity: 'critical', message: `堆内存使用率过高: ${process.memoryUsage.heapUsagePercent.toFixed(2)}%` }); analysis.health = 'critical'; } // 负载平均值分析 const cpuCount = os.cpus().length; if (system.loadAverage['5m'] > cpuCount * 0.8) { analysis.alerts.push({ type: 'high_load', severity: 'warning', message: `系统负载过高: ${system.loadAverage['5m'].toFixed(2)}` }); } // 生成建议 if (analysis.alerts.length > 0) { analysis.recommendations.push('考虑优化代码性能或增加系统资源'); } if (process.memoryUsage.heapUsagePercent > 70) { analysis.recommendations.push('建议进行垃圾回收优化或内存泄漏检查'); } return analysis; } /** * 清理历史数据 * @param {number} maxAge - 最大保留时间(毫秒) */ cleanup(maxAge = 86400000) { // 默认24小时 const cutoff = Date.now() - maxAge; let cleanedCount = 0; for (const [key, metrics] of this.metrics.entries()) { const originalLength = metrics.length; const filtered = metrics.filter(m => m.timestamp >= cutoff); if (filtered.length !== originalLength) { this.metrics.set(key, filtered); cleanedCount += originalLength - filtered.length; } } if (cleanedCount > 0) { this.logger.debug('性能数据清理完成', { cleanedCount }); } return cleanedCount; } /** * 重置所有指标 */ reset() { this.metrics.clear(); this.timers.clear(); this.counters.clear(); this.histograms.clear(); this.startTime = Date.now(); } /** * 销毁性能收集器 */ destroy() { this.stopMonitoring(); // 断开性能观察器 for (const observer of this.observers.values()) { observer.disconnect(); } this.observers.clear(); this.reset(); } } /** * 性能装饰器 * 用于自动测量函数执行时间 */ function performanceDecorator(name, collector) { return function (target, propertyKey, descriptor) { const originalMethod = descriptor.value; descriptor.value = async function (...args) { const timerName = name || `${target.constructor.name}.${propertyKey}`; collector.startTimer(timerName); try { const result = await originalMethod.apply(this, args); collector.incrementCounter(`${timerName}_success`); return result; } catch (error) { collector.incrementCounter(`${timerName}_error`); throw error; } finally { collector.endTimer(timerName); } }; return descriptor; }; } /** * 性能监控中间件 */ function createPerformanceMiddleware(collector) { return (req, res, next) => { const startTime = performance.now(); const timerName = `http_${req.method}_${req.path}`; collector.startTimer(timerName); collector.incrementCounter('http_requests_total'); // 监听响应结束 res.on('finish', () => { const duration = collector.endTimer(timerName); collector.incrementCounter(`http_responses_${res.statusCode}`); collector.addToHistogram('http_request_duration', duration); // 记录慢请求 if (duration > 1000) { collector.incrementCounter('http_slow_requests'); } }); next(); }; } module.exports = { PerformanceCollector, performanceDecorator, createPerformanceMiddleware };