UNPKG

@iota-big3/sdk-regulated

Version:

Regulated Industries SDK for Healthcare, Finance, and Government

345 lines 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RegulatedThresholds = exports.RegulatedDashboards = exports.PerformanceMonitor = void 0; const events_1 = require("events"); class PerformanceMonitor extends events_1.EventEmitter { constructor(logger) { super(); this.metrics = new Map(); this.thresholds = new Map(); this.dashboards = new Map(); this.collectors = new Map(); this.retentionPeriod = 24 * 60 * 60 * 1000; this.logger = logger; this.setupDefaultCollectors(); } record(metric) { const key = this.getMetricKey(metric.name, metric.tags); if (!this.metrics.has(key)) { this.metrics.set(key, []); } const metricArray = this.metrics.get(key); metricArray.push(metric); this.checkThresholds(metric); this.cleanupOldMetrics(key); this.emit('metricRecorded', metric); } async time(operation, tags, fn) { const start = process.hrtime.bigint(); try { const result = await fn(); const end = process.hrtime.bigint(); const duration = Number(end - start) / 1000000; this.record({ name: `${operation}.duration`, value: duration, unit: 'ms', timestamp: new Date(), tags: { ...tags, status: 'success' } }); return result; } catch (error) { const end = process.hrtime.bigint(); const duration = Number(end - start) / 1000000; this.record({ name: `${operation}.duration`, value: duration, unit: 'ms', timestamp: new Date(), tags: { ...tags, status: 'error', error: error.name } }); throw error; } } setThreshold(threshold) { const key = threshold.metric; if (!this.thresholds.has(key)) { this.thresholds.set(key, []); } this.thresholds.get(key).push(threshold); this.logger.info(`Set threshold for ${key}: ${threshold.operator} ${threshold.value}`); } createDashboard(dashboard) { this.dashboards.set(dashboard.id, dashboard); const timer = setInterval(() => { this.refreshDashboard(dashboard.id); }, dashboard.refreshInterval); this.collectors.set(`dashboard-${dashboard.id}`, timer); this.emit('dashboardCreated', dashboard); } getDashboardData(dashboardId) { const dashboard = this.dashboards.get(dashboardId); if (!dashboard) return null; const data = { dashboard, metrics: {}, lastUpdated: new Date() }; for (const metricName of dashboard.metrics) { const metrics = this.getMetrics(metricName); data.metrics[metricName] = { current: metrics[metrics.length - 1]?.value || 0, history: metrics.slice(-100), stats: this.calculateStats(metrics) }; } return data; } getMetrics(name, tags) { const key = this.getMetricKey(name, tags || {}); return this.metrics.get(key) || []; } calculateStats(metrics) { if (metrics.length === 0) { return { min: 0, max: 0, avg: 0, p50: 0, p95: 0, p99: 0 }; } const values = metrics.map(m => m.value).sort((a, b) => a - b); const sum = values.reduce((a, b) => a + b, 0); return { min: values[0], max: values[values.length - 1], avg: sum / values.length, p50: this.percentile(values, 0.5), p95: this.percentile(values, 0.95), p99: this.percentile(values, 0.99), count: values.length }; } setupDefaultCollectors() { const memoryCollector = setInterval(() => { const usage = process.memoryUsage(); this.record({ name: 'process.memory.heap_used', value: usage.heapUsed, unit: 'bytes', timestamp: new Date(), tags: { type: 'heap' } }); this.record({ name: 'process.memory.rss', value: usage.rss, unit: 'bytes', timestamp: new Date(), tags: { type: 'rss' } }); }, 10000); this.collectors.set('memory', memoryCollector); let lastCpuUsage = process.cpuUsage(); const cpuCollector = setInterval(() => { const currentCpuUsage = process.cpuUsage(lastCpuUsage); const totalUsage = (currentCpuUsage.user + currentCpuUsage.system) / 1000000; this.record({ name: 'process.cpu.usage', value: totalUsage, unit: 'ms', timestamp: new Date(), tags: { type: 'total' } }); lastCpuUsage = process.cpuUsage(); }, 10000); this.collectors.set('cpu', cpuCollector); let lastCheck = Date.now(); const lagCollector = setInterval(() => { const now = Date.now(); const lag = now - lastCheck - 1000; if (lag > 0) { this.record({ name: 'process.eventloop.lag', value: lag, unit: 'ms', timestamp: new Date(), tags: { type: 'lag' } }); } lastCheck = now; }, 1000); this.collectors.set('eventloop', lagCollector); } checkThresholds(metric) { const thresholds = this.thresholds.get(metric.name) || []; for (const threshold of thresholds) { let violated = false; switch (threshold.operator) { case '>': violated = metric.value > threshold.value; break; case '<': violated = metric.value < threshold.value; break; case '>=': violated = metric.value >= threshold.value; break; case '<=': violated = metric.value <= threshold.value; break; case '==': violated = metric.value === threshold.value; break; case '!=': violated = metric.value !== threshold.value; break; } if (violated) { const alert = { metric: metric.name, value: metric.value, threshold: threshold.value, operator: threshold.operator, severity: threshold.severity, description: threshold.description, timestamp: new Date(), tags: metric.tags }; this.logger.warn(`Performance threshold violated: ${metric.name} ${metric.value} ${threshold.operator} ${threshold.value}`); this.emit('thresholdViolated', alert); } } } cleanupOldMetrics(key) { const metrics = this.metrics.get(key); if (!metrics) return; const cutoff = Date.now() - this.retentionPeriod; const filtered = metrics.filter(m => m.timestamp.getTime() > cutoff); if (filtered.length < metrics.length) { this.metrics.set(key, filtered); } } refreshDashboard(dashboardId) { const data = this.getDashboardData(dashboardId); if (data) { this.emit('dashboardRefreshed', { dashboardId, data }); } } percentile(sortedValues, p) { const index = Math.ceil(sortedValues.length * p) - 1; return sortedValues[Math.max(0, index)]; } getMetricKey(name, tags) { const tagStr = Object.entries(tags) .sort(([a], [b]) => a.localeCompare(b)) .map(([k, v]) => `${k}:${v}`) .join(','); return tagStr ? `${name}{${tagStr}}` : name; } cleanup() { for (const [_, timer] of this.collectors) { clearInterval(timer); } this.collectors.clear(); this.removeAllListeners(); } } exports.PerformanceMonitor = PerformanceMonitor; exports.RegulatedDashboards = [ { id: 'healthcare-operations', name: 'Healthcare Operations Dashboard', refreshInterval: 5000, metrics: [ 'ehr.query.duration', 'patient.match.duration', 'hl7.parse.duration', 'fhir.validation.duration', 'encryption.phi.duration' ], layout: [ { type: 'timeseries', metric: 'ehr.query.duration', position: { x: 0, y: 0, w: 6, h: 4 } }, { type: 'gauge', metric: 'patient.match.duration', position: { x: 6, y: 0, w: 3, h: 4 } }, { type: 'counter', metric: 'hl7.parse.duration', position: { x: 9, y: 0, w: 3, h: 4 } } ] }, { id: 'finance-transactions', name: 'Financial Transaction Dashboard', refreshInterval: 1000, metrics: [ 'payment.process.duration', 'fraud.check.duration', 'pci.encryption.duration', 'ach.batch.size', 'transaction.volume' ], layout: [ { type: 'timeseries', metric: 'payment.process.duration', position: { x: 0, y: 0, w: 8, h: 4 } }, { type: 'heatmap', metric: 'fraud.check.duration', position: { x: 8, y: 0, w: 4, h: 4 } } ] }, { id: 'government-security', name: 'Government Security Dashboard', refreshInterval: 10000, metrics: [ 'piv.auth.duration', 'certificate.validation.duration', 'fedramp.scan.duration', 'audit.write.duration', 'session.active.count' ], layout: [ { type: 'gauge', metric: 'piv.auth.duration', position: { x: 0, y: 0, w: 4, h: 4 } }, { type: 'timeseries', metric: 'certificate.validation.duration', position: { x: 4, y: 0, w: 8, h: 4 } } ] } ]; exports.RegulatedThresholds = [ { metric: 'ehr.query.duration', operator: '>', value: 1000, severity: 'warning', description: 'EHR query taking longer than 1 second' }, { metric: 'patient.match.duration', operator: '>', value: 500, severity: 'critical', description: 'Patient matching exceeding 500ms SLA' }, { metric: 'payment.process.duration', operator: '>', value: 3000, severity: 'critical', description: 'Payment processing exceeding 3 second limit' }, { metric: 'fraud.check.duration', operator: '>', value: 200, severity: 'warning', description: 'Fraud check latency impacting user experience' }, { metric: 'piv.auth.duration', operator: '>', value: 5000, severity: 'critical', description: 'PIV authentication timeout risk' }, { metric: 'audit.write.duration', operator: '>', value: 100, severity: 'warning', description: 'Audit logging performance degradation' }, { metric: 'process.memory.heap_used', operator: '>', value: 1024 * 1024 * 1024, severity: 'warning', description: 'High memory usage detected' }, { metric: 'process.eventloop.lag', operator: '>', value: 100, severity: 'critical', description: 'Event loop blocking detected' } ]; //# sourceMappingURL=performance-monitor.js.map