@iota-big3/sdk-regulated
Version:
Regulated Industries SDK for Healthcare, Finance, and Government
345 lines • 12.1 kB
JavaScript
"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