UNPKG

network-performance-analyzer

Version:

Automated analysis tool for network performance test datasets containing DNS testing results and iperf3 performance measurements

271 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IperfAnalyzer = void 0; const ErrorHandler_1 = require("../utils/ErrorHandler"); /** * IperfAnalyzer class for processing iperf3 performance metrics * Analyzes bandwidth, latency, reliability, and CPU utilization across datasets */ class IperfAnalyzer { /** * Creates a new instance of IperfAnalyzer */ constructor() { this.errorHandler = new ErrorHandler_1.DefaultErrorHandler(); } /** * Analyze bandwidth metrics across datasets * @param datasets The datasets containing iperf test results * @returns Array of bandwidth metrics for each configuration */ analyzeBandwidth(datasets) { try { return datasets.map(dataset => { const iperfTests = this.getSuccessfulIperfTests(dataset, 'TCP Bandwidth'); // Extract bandwidth values const bandwidthValues = iperfTests.map(test => test.bandwidthMbps || 0); // Calculate metrics return { configuration: dataset.name, avgBandwidthMbps: this.calculateMean(bandwidthValues), medianBandwidthMbps: this.calculateMedian(bandwidthValues), maxBandwidthMbps: this.calculateMax(bandwidthValues), minBandwidthMbps: this.calculateMin(bandwidthValues), standardDeviation: this.calculateStandardDeviation(bandwidthValues), percentile95: this.calculatePercentile(bandwidthValues, 95), percentile99: this.calculatePercentile(bandwidthValues, 99) }; }); } catch (error) { const analysisError = new Error(error instanceof Error ? error.message : String(error)); analysisError.analysisType = 'bandwidth'; this.errorHandler.handleAnalysisError(analysisError); return []; } } /** * Analyze latency metrics across datasets * @param datasets The datasets containing iperf test results * @returns Array of latency metrics for each configuration */ analyzeLatency(datasets) { try { return datasets.map(dataset => { // For TCP tests, we don't have direct latency measurements, but we can use RTT if available // For UDP tests, we can use jitter as a latency-related metric const udpTests = this.getSuccessfulIperfTests(dataset, 'UDP'); // Extract jitter values from UDP tests const jitterValues = udpTests.map(test => test.jitterMs || 0); // For this implementation, we'll use jitter as our latency metric // In a real implementation, we might want to extract actual latency data if available return { configuration: dataset.name, avgLatencyMs: this.calculateMean(jitterValues), medianLatencyMs: this.calculateMedian(jitterValues), maxLatencyMs: this.calculateMax(jitterValues), minLatencyMs: this.calculateMin(jitterValues), jitterMs: this.calculateMean(jitterValues) }; }); } catch (error) { const analysisError = new Error(error instanceof Error ? error.message : String(error)); analysisError.analysisType = 'latency'; this.errorHandler.handleAnalysisError(analysisError); return []; } } /** * Analyze reliability metrics across datasets * @param datasets The datasets containing iperf test results * @returns Array of reliability metrics for each configuration */ analyzeReliability(datasets) { try { return datasets.map(dataset => { const allTests = this.getAllIperfTests(dataset); const tcpTests = this.getSuccessfulIperfTests(dataset, 'TCP'); const udpTests = this.getSuccessfulIperfTests(dataset, 'UDP'); // Calculate success rate const successRate = allTests.length > 0 ? allTests.filter(test => test.success).length / allTests.length : 0; // Calculate retransmit rate for TCP tests const retransmits = tcpTests.map(test => test.retransmits || 0); const totalRetransmits = retransmits.reduce((sum, val) => sum + val, 0); const retransmitRate = tcpTests.length > 0 ? totalRetransmits / tcpTests.length : 0; // Calculate packet loss rate for UDP tests const packetLossValues = udpTests.map(test => test.packetLoss || 0); const packetLossRate = this.calculateMean(packetLossValues); // Count errors const errorCount = allTests.filter(test => !test.success || test.error).length; return { configuration: dataset.name, successRate, retransmitRate, packetLossRate, errorCount }; }); } catch (error) { const analysisError = new Error(error instanceof Error ? error.message : String(error)); analysisError.analysisType = 'reliability'; this.errorHandler.handleAnalysisError(analysisError); return []; } } /** * Analyze CPU utilization metrics across datasets * @param datasets The datasets containing iperf test results * @returns Array of CPU utilization metrics for each configuration */ analyzeCpuUtilization(datasets) { try { return datasets.map(dataset => { const successfulTests = this.getSuccessfulIperfTests(dataset); // Extract CPU utilization values const hostCpuValues = successfulTests .map(test => test.cpuUtilizationHost || 0) .filter(val => val > 0); // Filter out zero values which might indicate missing data const remoteCpuValues = successfulTests .map(test => test.cpuUtilizationRemote || 0) .filter(val => val > 0); return { configuration: dataset.name, avgHostCpuUsage: this.calculateMean(hostCpuValues), avgRemoteCpuUsage: this.calculateMean(remoteCpuValues), maxHostCpuUsage: this.calculateMax(hostCpuValues), maxRemoteCpuUsage: this.calculateMax(remoteCpuValues) }; }); } catch (error) { const analysisError = new Error(error instanceof Error ? error.message : String(error)); analysisError.analysisType = 'cpu_utilization'; this.errorHandler.handleAnalysisError(analysisError); return []; } } /** * Get all iperf tests from a dataset * @param dataset The dataset to extract tests from * @returns Array of iperf test results */ getAllIperfTests(dataset) { try { // This is a placeholder - in a real implementation, we would need to load the results file // For now, we'll assume the dataset already has the parsed results return dataset.results?.iperfTests || []; } catch (error) { const analysisError = new Error(error instanceof Error ? error.message : String(error)); analysisError.analysisType = 'data_extraction'; analysisError.datasetName = dataset.name; this.errorHandler.handleAnalysisError(analysisError); return []; } } /** * Get successful iperf tests from a dataset, optionally filtered by scenario type * @param dataset The dataset to extract tests from * @param scenarioFilter Optional scenario type filter (e.g., 'TCP', 'UDP') * @returns Array of successful iperf test results */ getSuccessfulIperfTests(dataset, scenarioFilter) { const allTests = this.getAllIperfTests(dataset); return allTests.filter(test => { const isSuccess = test.success; const matchesScenario = !scenarioFilter || (test.scenario && test.scenario.includes(scenarioFilter)); return isSuccess && matchesScenario; }); } /** * Calculate the mean of an array of numbers * @param values Array of numbers * @returns The mean value, or 0 if the array is empty */ calculateMean(values) { if (values.length === 0) return 0; const sum = values.reduce((acc, val) => acc + val, 0); return sum / values.length; } /** * Calculate the median of an array of numbers * @param values Array of numbers * @returns The median value, or 0 if the array is empty */ calculateMedian(values) { if (values.length === 0) return 0; const sortedValues = [...values].sort((a, b) => a - b); const mid = Math.floor(sortedValues.length / 2); if (sortedValues.length % 2 === 0) { // For even-length arrays, average the two middle values const midValue1 = sortedValues[mid - 1] || 0; const midValue2 = sortedValues[mid] || 0; return (midValue1 + midValue2) / 2; } else { // For odd-length arrays, return the middle value return sortedValues[mid] || 0; } } /** * Calculate the maximum value in an array of numbers * @param values Array of numbers * @returns The maximum value, or 0 if the array is empty */ calculateMax(values) { if (values.length === 0) return 0; return Math.max(...values); } /** * Calculate the minimum value in an array of numbers * @param values Array of numbers * @returns The minimum value, or 0 if the array is empty */ calculateMin(values) { if (values.length === 0) return 0; return Math.min(...values); } /** * Calculate the standard deviation of an array of numbers * @param values Array of numbers * @returns The standard deviation, or 0 if the array is empty */ calculateStandardDeviation(values) { if (values.length === 0) return 0; const mean = this.calculateMean(values); const squaredDifferences = values.map(val => Math.pow(val - mean, 2)); const variance = this.calculateMean(squaredDifferences); return Math.sqrt(variance); } /** * Calculate a percentile value from an array of numbers * @param values Array of numbers * @param percentile The percentile to calculate (0-100) * @returns The percentile value, or 0 if the array is empty */ calculatePercentile(values, percentile) { if (values.length === 0) return 0; if (percentile < 0 || percentile > 100) { throw new Error(`Percentile must be between 0 and 100, got ${percentile}`); } const sortedValues = [...values].sort((a, b) => a - b); const index = Math.ceil((percentile / 100) * sortedValues.length) - 1; const safeIndex = Math.max(0, Math.min(index, sortedValues.length - 1)); return sortedValues[safeIndex] || 0; } } exports.IperfAnalyzer = IperfAnalyzer; //# sourceMappingURL=IperfAnalyzer.js.map