UNPKG

@iota-big3/sdk-gateway

Version:

Universal API Gateway with protocol translation, intelligent routing, rate limiting, health checking, and caching

227 lines 7.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SLAMonitor = void 0; const events_1 = require("events"); class SLAMonitor extends events_1.EventEmitter { constructor() { super(); this.slaConfigs = new Map(); this.violations = []; this.metrics = new Map(); this.isEnabled = true; } addSLA(routePath, slaConfig) { if (!this.isEnabled) { return; } this.slaConfigs.set(routePath, slaConfig); this.metrics.set(routePath, { responseTime: [], errorCount: 0, totalRequests: 0, lastReset: Date.now() }); this.emit('sla:added', { routePath, slaConfig, timestamp: Date.now() }); } removeSLA(routePath) { if (!this.isEnabled) { return; } this.slaConfigs.delete(routePath); this.metrics.delete(routePath); this.emit('sla:removed', { routePath, timestamp: Date.now() }); } recordRequest(routePath, request, response) { if (!this.isEnabled) { return; } const slaConfig = this.slaConfigs.get(routePath); if (!slaConfig) { return; } const routeMetrics = this.metrics.get(routePath); if (!routeMetrics) { return; } // Record metrics routeMetrics.totalRequests++; if (response.latency !== undefined) { routeMetrics.responseTime.push(response.latency); } if (response.statusCode >= 400) { routeMetrics.errorCount++; } // Check for SLA violations this.checkViolations(routePath, slaConfig, routeMetrics, response); } checkViolations(routePath, slaConfig, routeMetrics, response) { const violations = []; // Check response time violation if (response.latency !== undefined && response.latency > slaConfig.responseTime) { violations.push({ type: 'response_time', threshold: slaConfig.responseTime, actual: response.latency, timestamp: Date.now(), route: routePath }); } // Check error rate violation const errorRate = routeMetrics.errorCount / routeMetrics.totalRequests; if (errorRate > slaConfig.errorRate) { violations.push({ type: 'error_rate', threshold: slaConfig.errorRate, actual: errorRate, timestamp: Date.now(), route: routePath }); } // Check availability violation (simplified) const availability = (routeMetrics.totalRequests - routeMetrics.errorCount) / routeMetrics.totalRequests; if (availability < slaConfig.availability) { violations.push({ type: 'availability', threshold: slaConfig.availability, actual: availability, timestamp: Date.now(), route: routePath }); } // Process violations violations.forEach(violation => { this.violations.push(violation); this.emit('sla:violation', violation); // Execute actions if configured if (slaConfig.actions) { slaConfig.actions.forEach(action => { this.executeAction(action, violation); }); } }); } executeAction(action, violation) { if (!this.isEnabled) { return; } this.emit('sla:action', { action, violation, timestamp: Date.now() }); // In real implementation, would execute specific actions like: // - Send alerts // - Scale services // - Circuit breaker activation // - Logging } getViolations(routePath) { if (routePath) { return this.violations.filter(v => v.route === routePath); } return [...this.violations]; } getSLAStatus(routePath) { if (!this.isEnabled) { return null; } const slaConfig = this.slaConfigs.get(routePath); const routeMetrics = this.metrics.get(routePath); if (!slaConfig || !routeMetrics) { return null; } const responseTimes = routeMetrics.responseTime; const averageResponseTime = responseTimes.length > 0 ? responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length : 0; const sortedTimes = [...responseTimes].sort((a, b) => a - b); const p95Index = Math.floor(sortedTimes.length * 0.95); const p95ResponseTime = sortedTimes[p95Index] || 0; const errorRate = routeMetrics.totalRequests > 0 ? routeMetrics.errorCount / routeMetrics.totalRequests : 0; const availability = routeMetrics.totalRequests > 0 ? (routeMetrics.totalRequests - routeMetrics.errorCount) / routeMetrics.totalRequests : 1; const isCompliant = averageResponseTime <= slaConfig.responseTime && errorRate <= slaConfig.errorRate && availability >= slaConfig.availability; return { isCompliant, responseTime: { average: averageResponseTime, p95: p95ResponseTime, threshold: slaConfig.responseTime }, errorRate: { current: errorRate, threshold: slaConfig.errorRate }, availability: { current: availability, threshold: slaConfig.availability } }; } resetMetrics(routePath) { if (!this.isEnabled) { return; } if (routePath) { const routeMetrics = this.metrics.get(routePath); if (routeMetrics) { routeMetrics.responseTime = []; routeMetrics.errorCount = 0; routeMetrics.totalRequests = 0; routeMetrics.lastReset = Date.now(); } } else { this.metrics.forEach(routeMetrics => { routeMetrics.responseTime = []; routeMetrics.errorCount = 0; routeMetrics.totalRequests = 0; routeMetrics.lastReset = Date.now(); }); } this.emit('metrics:reset', { routePath, timestamp: Date.now() }); } clearViolations(routePath) { if (!this.isEnabled) { return; } if (routePath) { this.violations = this.violations.filter(v => v.route !== routePath); } else { this.violations = []; } this.emit('violations:cleared', { routePath, timestamp: Date.now() }); } getAllSLAs() { return new Map(this.slaConfigs); } enable() { this.isEnabled = true; this.emit('sla:enabled', { timestamp: Date.now() }); } disable() { this.isEnabled = false; this.emit('sla:disabled', { timestamp: Date.now() }); } isSLAEnabled() { return this.isEnabled; } } exports.SLAMonitor = SLAMonitor; //# sourceMappingURL=sla-monitor.js.map