@casoon/auditmysite
Version:
A comprehensive command-line tool for automated accessibility, security, performance, and SEO testing using Playwright and pa11y, based on sitemap URLs
272 lines • 9.81 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResourceMonitor = void 0;
const events_1 = require("events");
class ResourceMonitor extends events_1.EventEmitter {
constructor(options = {}) {
super();
this.isMonitoring = false;
this.intervalId = null;
this.startTime = null;
this.metrics = null;
this.alerts = [];
this.networkStats = {
activeConnections: 0,
bytesReceived: 0,
bytesSent: 0,
requestsPerSecond: 0,
lastRequestCount: 0,
lastRequestTime: Date.now()
};
this.options = {
enabled: true,
interval: 1000, // 1 Sekunde
limits: {
maxMemoryUsage: 512, // 512 MB
maxCpuUsage: 80, // 80%
maxNetworkConnections: 100,
maxRequestsPerSecond: 50
},
enableAlerts: true,
enableLogging: true,
enableThrottling: true,
...options
};
}
async start() {
if (this.isMonitoring) {
return;
}
this.isMonitoring = true;
this.startTime = new Date();
this.alerts = [];
console.log('📊 Starting Resource Monitor...');
this.intervalId = setInterval(() => {
this.collectMetrics();
}, this.options.interval);
this.emit('monitor:started', { timestamp: new Date() });
}
stop() {
if (!this.isMonitoring) {
return;
}
this.isMonitoring = false;
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
console.log('📊 Resource Monitor stopped');
this.emit('monitor:stopped', { timestamp: new Date() });
}
collectMetrics() {
try {
this.metrics = {
memory: this.getMemoryMetrics(),
cpu: this.getCpuMetrics(),
network: this.getNetworkMetrics(),
system: this.getSystemMetrics()
};
// Alerts prüfen
if (this.options.enableAlerts) {
this.checkAlerts();
}
// Event emittieren
this.emit('metrics:collected', {
metrics: this.metrics,
timestamp: new Date()
});
// Logging
if (this.options.enableLogging) {
this.logMetrics();
}
}
catch (error) {
console.error('Error collecting metrics:', error);
this.emit('monitor:error', { error: String(error), timestamp: new Date() });
}
}
getMemoryMetrics() {
const memUsage = process.memoryUsage();
const totalMem = require('os').totalmem() / 1024 / 1024; // MB
const usedMem = totalMem - (require('os').freemem() / 1024 / 1024); // MB
return {
used: Math.round(usedMem),
total: Math.round(totalMem),
percentage: Math.round((usedMem / totalMem) * 100),
heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024),
heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024),
external: Math.round(memUsage.external / 1024 / 1024)
};
}
getCpuMetrics() {
const os = require('os');
const cpus = os.cpus();
// CPU Usage berechnen (vereinfacht)
const totalIdle = cpus.reduce((sum, cpu) => sum + cpu.times.idle, 0);
const totalTick = cpus.reduce((sum, cpu) => {
return sum + cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.idle + cpu.times.irq;
}, 0);
const idle = totalIdle / cpus.length;
const total = totalTick / cpus.length;
const usage = Math.round(((total - idle) / total) * 100);
return {
usage,
loadAverage: os.loadavg(),
uptime: os.uptime()
};
}
getNetworkMetrics() {
return {
activeConnections: this.networkStats.activeConnections,
bytesReceived: this.networkStats.bytesReceived,
bytesSent: this.networkStats.bytesSent,
requestsPerSecond: this.networkStats.requestsPerSecond
};
}
getSystemMetrics() {
const os = require('os');
return {
uptime: os.uptime(),
platform: os.platform(),
arch: os.arch(),
nodeVersion: process.version
};
}
checkAlerts() {
if (!this.metrics)
return;
const alerts = [];
// Memory Alerts
if (this.metrics.memory.percentage > this.options.limits.maxMemoryUsage) {
alerts.push({
type: 'memory',
level: this.metrics.memory.percentage > 90 ? 'critical' : 'warning',
message: `High memory usage: ${this.metrics.memory.percentage}%`,
value: this.metrics.memory.percentage,
limit: this.options.limits.maxMemoryUsage,
timestamp: new Date()
});
}
// CPU Alerts
if (this.metrics.cpu.usage > this.options.limits.maxCpuUsage) {
alerts.push({
type: 'cpu',
level: this.metrics.cpu.usage > 90 ? 'critical' : 'warning',
message: `High CPU usage: ${this.metrics.cpu.usage}%`,
value: this.metrics.cpu.usage,
limit: this.options.limits.maxCpuUsage,
timestamp: new Date()
});
}
// Network Alerts
if (this.metrics.network.activeConnections > this.options.limits.maxNetworkConnections) {
alerts.push({
type: 'network',
level: 'warning',
message: `High network connections: ${this.metrics.network.activeConnections}`,
value: this.metrics.network.activeConnections,
limit: this.options.limits.maxNetworkConnections,
timestamp: new Date()
});
}
if (this.metrics.network.requestsPerSecond > this.options.limits.maxRequestsPerSecond) {
alerts.push({
type: 'network',
level: 'warning',
message: `High request rate: ${this.metrics.network.requestsPerSecond} req/s`,
value: this.metrics.network.requestsPerSecond,
limit: this.options.limits.maxRequestsPerSecond,
timestamp: new Date()
});
}
// Neue Alerts hinzufügen
this.alerts.push(...alerts);
// Alerts emittieren
alerts.forEach(alert => {
this.emit('alert:triggered', alert);
if (alert.level === 'critical') {
console.error(`🚨 CRITICAL: ${alert.message}`);
}
else {
console.warn(`⚠️ WARNING: ${alert.message}`);
}
});
}
logMetrics() {
if (!this.metrics)
return;
const { memory, cpu, network } = this.metrics;
console.log(`📊 Resources: 💾 ${memory.percentage}% | 🔥 ${cpu.usage}% | 🌐 ${network.activeConnections} conn | 📡 ${network.requestsPerSecond.toFixed(1)} req/s`);
}
// Network Stats aktualisieren
recordRequest() {
this.networkStats.activeConnections++;
this.networkStats.lastRequestCount++;
const now = Date.now();
const timeDiff = (now - this.networkStats.lastRequestTime) / 1000; // Sekunden
if (timeDiff >= 1) {
this.networkStats.requestsPerSecond = this.networkStats.lastRequestCount / timeDiff;
this.networkStats.lastRequestCount = 0;
this.networkStats.lastRequestTime = now;
}
}
recordRequestComplete() {
this.networkStats.activeConnections = Math.max(0, this.networkStats.activeConnections - 1);
}
recordNetworkTraffic(bytesReceived, bytesSent) {
this.networkStats.bytesReceived += bytesReceived;
this.networkStats.bytesSent += bytesSent;
}
// Throttling basierend auf Ressourcen
shouldThrottle() {
if (!this.options.enableThrottling || !this.metrics) {
return false;
}
return (this.metrics.memory.percentage > this.options.limits.maxMemoryUsage ||
this.metrics.cpu.usage > this.options.limits.maxCpuUsage ||
this.metrics.network.activeConnections > this.options.limits.maxNetworkConnections);
}
// Getter-Methoden
getMetrics() {
return this.metrics;
}
getAlerts() {
return this.alerts;
}
getCriticalAlerts() {
return this.alerts.filter(alert => alert.level === 'critical');
}
getWarningAlerts() {
return this.alerts.filter(alert => alert.level === 'warning');
}
getUptime() {
if (!this.startTime)
return 0;
return Date.now() - this.startTime.getTime();
}
getMonitoringStatus() {
return this.isMonitoring;
}
// Konfiguration ändern
updateLimits(limits) {
this.options.limits = { ...this.options.limits, ...limits };
}
updateInterval(interval) {
this.options.interval = interval;
if (this.isMonitoring && this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = setInterval(() => {
this.collectMetrics();
}, interval);
}
}
// Cleanup
async cleanup() {
this.stop();
this.alerts = [];
this.metrics = null;
this.startTime = null;
}
}
exports.ResourceMonitor = ResourceMonitor;
//# sourceMappingURL=resource-monitor.js.map