fortify2-js
Version:
MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.
163 lines (160 loc) • 5.68 kB
JavaScript
'use strict';
/**
* FortifyJS Performance Monitor
* Real-time performance monitoring and optimization
*/
class PerformanceMonitor {
constructor(config = {}) {
this.metrics = {};
this.alerts = [];
this.interval = null;
this.config = {
enabled: true,
metrics: ["cpu", "memory", "responseTime", "requests", "errors"],
interval: 5000,
alerts: [],
dashboard: false,
export: {},
...config,
};
this.initializeMetrics();
if (this.config.enabled) {
this.startMonitoring();
}
}
initializeMetrics() {
this.metrics = {
requests: { total: 0, perSecond: 0, lastCount: 0 },
responses: { total: 0, average: 0, min: Infinity, max: 0 },
errors: { total: 0, rate: 0 },
memory: { used: 0, total: 0, percentage: 0 },
cpu: { usage: 0 },
uptime: 0,
timestamp: Date.now(),
};
}
getMiddleware() {
return (req, res, next) => {
if (!this.config.enabled) {
return next();
}
const startTime = process.hrtime.bigint();
this.metrics.requests.total++;
res.on("finish", () => {
const duration = Number(process.hrtime.bigint() - startTime) / 1000000;
// Update response metrics
this.metrics.responses.total++;
this.metrics.responses.min = Math.min(this.metrics.responses.min, duration);
this.metrics.responses.max = Math.max(this.metrics.responses.max, duration);
this.metrics.responses.average =
(this.metrics.responses.average *
(this.metrics.responses.total - 1) +
duration) /
this.metrics.responses.total;
// Track errors
if (res.statusCode >= 400) {
this.metrics.errors.total++;
}
// Add performance headers
res.set("X-Response-Time", `${duration.toFixed(2)}ms`);
});
next();
};
}
startMonitoring() {
this.interval = setInterval(() => {
this.collectMetrics();
this.checkAlerts();
if (this.config.export.custom) {
this.config.export.custom(this.metrics);
}
}, this.config.interval);
}
collectMetrics() {
// Memory metrics
const memUsage = process.memoryUsage();
this.metrics.memory = {
used: Math.round(memUsage.heapUsed / 1024 / 1024),
total: Math.round(memUsage.heapTotal / 1024 / 1024),
percentage: (memUsage.heapUsed / memUsage.heapTotal) * 100,
};
// CPU metrics (simplified) but we can use external lib (if exist)
this.metrics.cpu.usage = process.cpuUsage();
// Request rate
const requestDiff = this.metrics.requests.total - this.metrics.requests.lastCount;
this.metrics.requests.perSecond =
requestDiff / (this.config.interval / 1000);
this.metrics.requests.lastCount = this.metrics.requests.total;
// Error rate
this.metrics.errors.rate =
this.metrics.requests.total > 0
? (this.metrics.errors.total / this.metrics.requests.total) *
100
: 0;
// Uptime
this.metrics.uptime = process.uptime();
this.metrics.timestamp = Date.now();
}
checkAlerts() {
for (const alert of this.config.alerts) {
const value = this.getMetricValue(alert.metric);
if (value > alert.threshold) {
({
metric: alert.metric,
value,
threshold: alert.threshold,
timestamp: Date.now(),
action: alert.action,
});
}
}
}
getMetricValue(metric) {
switch (metric) {
case "memory":
return this.metrics.memory.percentage;
case "cpu":
return this.metrics.cpu.usage;
case "responseTime":
return this.metrics.responses.average;
case "errorRate":
return this.metrics.errors.rate;
case "requestRate":
return this.metrics.requests.perSecond;
default:
return 0;
}
}
getMetrics() {
return {
...this.metrics,
alerts: this.alerts.slice(-10), // Last 10 alerts
};
}
getHealthStatus() {
const health = {
status: "healthy",
checks: {
memory: this.metrics.memory.percentage < 80 ? "healthy" : "warning",
responseTime: this.metrics.responses.average < 1000
? "healthy"
: "warning",
errorRate: this.metrics.errors.rate < 5 ? "healthy" : "warning",
},
uptime: this.metrics.uptime,
timestamp: Date.now(),
};
// Determine overall status
const hasWarnings = Object.values(health.checks).includes("warning");
health.status = hasWarnings ? "warning" : "healthy";
return health;
}
stop() {
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
}
}
exports.PerformanceMonitor = PerformanceMonitor;
//# sourceMappingURL=performance-monitor.js.map