UNPKG

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.

238 lines (235 loc) 9.34 kB
'use strict'; /** * Performance Monitoring Utilities for FortifyJS * Monitor and optimize cryptographic operations performance */ /** * Performance monitor for cryptographic operations */ class CryptoPerformanceMonitor { constructor() { this.metrics = []; this.activeOperations = new Map(); this.benchmarks = new Map(); } /** * Start monitoring an operation */ startOperation(operationId, operationName, metadata) { const metric = { operationName, startTime: process.hrtime.bigint(), memoryUsage: process.memoryUsage(), cpuUsage: process.cpuUsage(), success: false, ...metadata, }; this.activeOperations.set(operationId, metric); } /** * End monitoring an operation */ endOperation(operationId, success = true, errorType) { const metric = this.activeOperations.get(operationId); if (!metric) { console.warn(`No active operation found for ID: ${operationId}`); return null; } metric.endTime = process.hrtime.bigint(); metric.duration = Number(metric.endTime - metric.startTime) / 1000000; // Convert to milliseconds metric.success = success; metric.errorType = errorType; // Calculate memory and CPU usage const currentMemory = process.memoryUsage(); const currentCpu = process.cpuUsage(metric.cpuUsage); metric.memoryUsage = { rss: currentMemory.rss - (metric.memoryUsage?.rss || 0), heapTotal: currentMemory.heapTotal - (metric.memoryUsage?.heapTotal || 0), heapUsed: currentMemory.heapUsed - (metric.memoryUsage?.heapUsed || 0), external: currentMemory.external - (metric.memoryUsage?.external || 0), arrayBuffers: currentMemory.arrayBuffers - (metric.memoryUsage?.arrayBuffers || 0), }; metric.cpuUsage = currentCpu; this.metrics.push(metric); this.activeOperations.delete(operationId); return metric; } /** * Get performance statistics for an operation type */ getOperationStats(operationName) { const operationMetrics = this.metrics.filter(m => m.operationName === operationName); if (operationMetrics.length === 0) { return { totalOperations: 0, successfulOperations: 0, failedOperations: 0, avgDuration: 0, minDuration: 0, maxDuration: 0, successRate: 0, avgMemoryUsage: 0, }; } const successful = operationMetrics.filter(m => m.success); const durations = operationMetrics.map(m => m.duration || 0); const memoryUsages = operationMetrics.map(m => m.memoryUsage?.heapUsed || 0); return { totalOperations: operationMetrics.length, successfulOperations: successful.length, failedOperations: operationMetrics.length - successful.length, avgDuration: durations.reduce((a, b) => a + b, 0) / durations.length, minDuration: Math.min(...durations), maxDuration: Math.max(...durations), successRate: (successful.length / operationMetrics.length) * 100, avgMemoryUsage: memoryUsages.reduce((a, b) => a + b, 0) / memoryUsages.length, }; } /** * Benchmark a cryptographic operation */ async benchmarkOperation(operationName, operation, iterations = 100, metadata) { const results = []; let successCount = 0; let maxMemory = 0; const recommendations = []; console.log(`Starting benchmark for ${operationName} (${iterations} iterations)...`); for (let i = 0; i < iterations; i++) { const operationId = `benchmark_${operationName}_${i}`; try { this.startOperation(operationId, operationName, metadata); await operation(); const metric = this.endOperation(operationId, true); if (metric) { results.push(metric.duration || 0); successCount++; maxMemory = Math.max(maxMemory, metric.memoryUsage?.heapUsed || 0); } } catch (error) { this.endOperation(operationId, false, error.name); } } const avgDuration = results.reduce((a, b) => a + b, 0) / results.length; const minDuration = Math.min(...results); const maxDuration = Math.max(...results); const successRate = (successCount / iterations) * 100; // Generate performance recommendations if (avgDuration > 1000) { recommendations.push('Operation is slow - consider optimizing algorithm or key size'); } if (successRate < 95) { recommendations.push('Low success rate detected - investigate error causes'); } if (maxMemory > 100 * 1024 * 1024) { // 100MB recommendations.push('High memory usage detected - consider memory optimization'); } if (metadata?.keySize && metadata.keySize > 4096) { recommendations.push('Large key size may impact performance - consider if necessary'); } const benchmark = { operation: operationName, algorithm: metadata?.algorithm || 'unknown', keySize: metadata?.keySize || 0, dataSize: metadata?.dataSize || 0, iterations, avgDuration, minDuration, maxDuration, successRate, memoryPeak: maxMemory, recommendations, }; const benchmarkKey = `${operationName}_${metadata?.algorithm}_${metadata?.keySize}`; this.benchmarks.set(benchmarkKey, benchmark); return benchmark; } /** * Get performance recommendations based on collected metrics */ getPerformanceRecommendations() { const recommendations = []; const stats = new Map(); // Collect stats for each operation type const operationTypes = [...new Set(this.metrics.map(m => m.operationName))]; for (const opType of operationTypes) { stats.set(opType, this.getOperationStats(opType)); } // Analyze and generate recommendations for (const [operation, stat] of stats.entries()) { if (stat.successRate < 95) { recommendations.push(`${operation}: Low success rate (${stat.successRate.toFixed(1)}%) - investigate errors`); } if (stat.avgDuration > 1000) { recommendations.push(`${operation}: Slow performance (${stat.avgDuration.toFixed(1)}ms avg) - consider optimization`); } if (stat.avgMemoryUsage > 50 * 1024 * 1024) { // 50MB recommendations.push(`${operation}: High memory usage (${(stat.avgMemoryUsage / 1024 / 1024).toFixed(1)}MB avg) - optimize memory usage`); } } // General recommendations if (this.metrics.length > 1000) { recommendations.push('Large number of operations recorded - consider clearing old metrics'); } return recommendations; } /** * Clear old metrics to prevent memory leaks */ clearOldMetrics(maxAge = 3600000) { const cutoff = Date.now() - maxAge; this.metrics = this.metrics.filter(metric => { const metricTime = Number(metric.startTime) / 1000000; // Convert to milliseconds return metricTime > cutoff; }); } /** * Export metrics for external analysis */ exportMetrics() { const summary = {}; const operationTypes = [...new Set(this.metrics.map(m => m.operationName))]; for (const opType of operationTypes) { summary[opType] = this.getOperationStats(opType); } return { metrics: this.metrics, benchmarks: Array.from(this.benchmarks.values()), summary, }; } /** * Monitor system resources */ getSystemResourceUsage() { return { memory: process.memoryUsage(), cpu: process.cpuUsage(), uptime: process.uptime(), loadAverage: require('os').loadavg(), }; } /** * Performance-aware operation wrapper */ async monitoredOperation(operationName, operation, metadata) { const operationId = `${operationName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; try { this.startOperation(operationId, operationName, metadata); const result = await operation(); this.endOperation(operationId, true); return result; } catch (error) { this.endOperation(operationId, false, error.name); throw error; } } } /** * Global performance monitor instance */ const globalPerformanceMonitor = new CryptoPerformanceMonitor(); exports.CryptoPerformanceMonitor = CryptoPerformanceMonitor; exports.globalPerformanceMonitor = globalPerformanceMonitor; //# sourceMappingURL=performanceMonitor.js.map