UNPKG

@ai-capabilities-suite/mcp-debugger-core

Version:

Core debugging engine for Node.js and TypeScript applications. Provides Inspector Protocol integration, breakpoint management, variable inspection, execution control, profiling, hang detection, and source map support.

241 lines 7.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetricsCollector = exports.MetricType = void 0; /** * Metric types for tracking different aspects of the debugger */ var MetricType; (function (MetricType) { MetricType["SESSION_DURATION"] = "session_duration"; MetricType["SESSION_COUNT"] = "session_count"; MetricType["BREAKPOINT_HIT"] = "breakpoint_hit"; MetricType["OPERATION_LATENCY"] = "operation_latency"; MetricType["ERROR_RATE"] = "error_rate"; })(MetricType || (exports.MetricType = MetricType = {})); /** * Metrics collector for enterprise observability * Tracks session metrics, operation latencies, and error rates */ class MetricsCollector { constructor() { this.metrics = []; this.sessionStartTimes = new Map(); this.breakpointHitCounts = new Map(); this.operationStartTimes = new Map(); this.errorCounts = new Map(); this.maxMetricsSize = 10000; } /** * Record a session start */ recordSessionStart(sessionId) { this.sessionStartTimes.set(sessionId, Date.now()); this.recordMetric(MetricType.SESSION_COUNT, 1, { action: "start" }); } /** * Record a session end and calculate duration */ recordSessionEnd(sessionId) { const startTime = this.sessionStartTimes.get(sessionId); if (startTime) { const duration = Date.now() - startTime; this.recordMetric(MetricType.SESSION_DURATION, duration, { sessionId }); this.sessionStartTimes.delete(sessionId); } this.recordMetric(MetricType.SESSION_COUNT, 1, { action: "end" }); } /** * Record a breakpoint hit */ recordBreakpointHit(breakpointId, sessionId) { const currentCount = this.breakpointHitCounts.get(breakpointId) || 0; this.breakpointHitCounts.set(breakpointId, currentCount + 1); const labels = { breakpointId }; if (sessionId) { labels["sessionId"] = sessionId; } this.recordMetric(MetricType.BREAKPOINT_HIT, 1, labels); } /** * Start tracking an operation */ startOperation(operationId, operationType) { this.operationStartTimes.set(operationId, Date.now()); } /** * End tracking an operation and record latency */ endOperation(operationId, operationType, success = true) { const startTime = this.operationStartTimes.get(operationId); if (startTime) { const latency = Date.now() - startTime; this.recordMetric(MetricType.OPERATION_LATENCY, latency, { operationType, success: success.toString(), }); this.operationStartTimes.delete(operationId); } if (!success) { this.recordError(operationType); } } /** * Record an error */ recordError(errorType) { const currentCount = this.errorCounts.get(errorType) || 0; this.errorCounts.set(errorType, currentCount + 1); this.recordMetric(MetricType.ERROR_RATE, 1, { errorType }); } /** * Record a generic metric */ recordMetric(type, value, labels) { const entry = { type, timestamp: Date.now(), value, labels, }; this.metrics.push(entry); // Limit metrics size to prevent memory issues if (this.metrics.length > this.maxMetricsSize) { this.metrics.shift(); } } /** * Get all metrics */ getAllMetrics() { return [...this.metrics]; } /** * Get metrics by type */ getMetricsByType(type) { return this.metrics.filter((m) => m.type === type); } /** * Get metrics within a time range */ getMetricsInRange(startTime, endTime) { return this.metrics.filter((m) => m.timestamp >= startTime && m.timestamp <= endTime); } /** * Calculate statistics for a set of metrics */ calculateStats(values) { if (values.length === 0) { return { count: 0, sum: 0, min: 0, max: 0, avg: 0, }; } const sorted = [...values].sort((a, b) => a - b); const sum = values.reduce((acc, val) => acc + val, 0); return { count: values.length, sum, min: sorted[0], max: sorted[sorted.length - 1], avg: sum / values.length, p50: sorted[Math.floor(sorted.length * 0.5)], p95: sorted[Math.floor(sorted.length * 0.95)], p99: sorted[Math.floor(sorted.length * 0.99)], }; } /** * Get summary statistics for all metrics */ getSummary() { const summary = {}; // Group metrics by type const metricsByType = new Map(); for (const metric of this.metrics) { if (!metricsByType.has(metric.type)) { metricsByType.set(metric.type, []); } metricsByType.get(metric.type).push(metric.value); } // Calculate stats for each type for (const [type, values] of metricsByType.entries()) { summary[type] = this.calculateStats(values); } return summary; } /** * Get active session count */ getActiveSessionCount() { return this.sessionStartTimes.size; } /** * Get breakpoint hit count for a specific breakpoint */ getBreakpointHitCount(breakpointId) { return this.breakpointHitCounts.get(breakpointId) || 0; } /** * Get all breakpoint hit counts */ getAllBreakpointHitCounts() { return new Map(this.breakpointHitCounts); } /** * Get error count for a specific error type */ getErrorCount(errorType) { return this.errorCounts.get(errorType) || 0; } /** * Get all error counts */ getAllErrorCounts() { return new Map(this.errorCounts); } /** * Get total error count */ getTotalErrorCount() { let total = 0; for (const count of this.errorCounts.values()) { total += count; } return total; } /** * Clear all metrics */ clearMetrics() { this.metrics = []; this.sessionStartTimes.clear(); this.breakpointHitCounts.clear(); this.operationStartTimes.clear(); this.errorCounts.clear(); } /** * Export metrics in a format suitable for external monitoring systems */ exportMetrics() { return { metrics: this.getAllMetrics(), summary: this.getSummary(), activeSessionCount: this.getActiveSessionCount(), breakpointHitCounts: Object.fromEntries(this.breakpointHitCounts), errorCounts: Object.fromEntries(this.errorCounts), totalErrors: this.getTotalErrorCount(), }; } /** * Get metrics endpoint data (for HTTP endpoint) */ getMetricsEndpointData() { const data = this.exportMetrics(); return JSON.stringify(data, null, 2); } } exports.MetricsCollector = MetricsCollector; //# sourceMappingURL=metrics-collector.js.map