Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | 1x 1x 1x 1x 1x 1x 1x | const si = require('systeminformation');
const pidusage = require('pidusage');
const fs = require('fs').promises;
const path = require('path');
const logger = require('./logger');
class MetricsCollector {
constructor() {
this.lastNetworkStats = null;
}
async collectSystemMetrics() {
try {
const metrics = {};
// CPU information
const cpuLoad = await si.currentLoad();
metrics.cpuUsage = cpuLoad.currentLoad;
// Memory information
const mem = await si.mem();
metrics.ramUsage = (mem.used / 1024 / 1024); // Convert to MB
metrics.ramTotal = (mem.total / 1024 / 1024); // Convert to MB
// Disk information
const fsSize = await si.fsSize();
if (fsSize && fsSize.length > 0) {
// Sum up all disk usage
const totalUsed = fsSize.reduce((sum, disk) => sum + disk.used, 0);
const totalSize = fsSize.reduce((sum, disk) => sum + disk.size, 0);
metrics.diskUsage = totalUsed / 1024 / 1024; // Convert to MB
metrics.diskTotal = totalSize / 1024 / 1024; // Convert to MB
}
// Network information
const networkStats = await si.networkStats();
if (networkStats && networkStats.length > 0) {
const primaryInterface = networkStats[0];
if (this.lastNetworkStats) {
// Calculate delta from last measurement
const timeDiff = Date.now() - this.lastNetworkStats.timestamp;
const rxDiff = primaryInterface.rx_bytes - this.lastNetworkStats.rx_bytes;
const txDiff = primaryInterface.tx_bytes - this.lastNetworkStats.tx_bytes;
metrics.networkIn = (rxDiff / 1024 / 1024) / (timeDiff / 1000); // MB/s
metrics.networkOut = (txDiff / 1024 / 1024) / (timeDiff / 1000); // MB/s
}
this.lastNetworkStats = {
rx_bytes: primaryInterface.rx_bytes,
tx_bytes: primaryInterface.tx_bytes,
timestamp: Date.now()
};
}
// Process count
const processes = await si.processes();
metrics.processCount = processes.all;
// System load (Linux/macOS)
try {
const load = await si.currentLoad();
metrics.loadAverage = load.avgLoad;
} catch (error) {
// Load average might not be available on Windows
logger.debug('Load average not available:', error.message);
}
metrics.timestamp = new Date();
return metrics;
} catch (error) {
logger.error('Error collecting system metrics:', error);
throw error;
}
}
async collectProjectMetrics(projectConfig) {
try {
const metrics = {
projectName: projectConfig.project_name,
timestamp: new Date()
};
// Check if project directory exists
try {
await fs.access(projectConfig.pwd_path);
// Get directory size
const dirSize = await this.getDirectorySize(projectConfig.pwd_path);
metrics.projectDiskUsage = dirSize / 1024 / 1024; // Convert to MB
// Check if there are any processes running in the project directory
// This is a simplified approach - in production, you might want to track specific PIDs
const processes = await si.processes();
const projectProcesses = processes.list.filter(proc =>
proc.command && proc.command.includes(projectConfig.pwd_path)
);
if (projectProcesses.length > 0) {
let totalCpu = 0;
let totalMem = 0;
for (const proc of projectProcesses) {
try {
const procStats = await pidusage(proc.pid);
totalCpu += procStats.cpu;
totalMem += procStats.memory / 1024 / 1024; // Convert to MB
} catch (procError) {
// Process might have ended
logger.debug(`Process ${proc.pid} not found:`, procError.message);
}
}
metrics.projectCpuUsage = totalCpu;
metrics.projectRamUsage = totalMem;
metrics.projectProcessCount = projectProcesses.length;
}
} catch (accessError) {
logger.warn(`Project directory not accessible: ${projectConfig.pwd_path}`, accessError);
}
return metrics;
} catch (error) {
logger.error('Error collecting project metrics:', error);
throw error;
}
}
async getDirectorySize(dirPath) {
let totalSize = 0;
try {
const items = await fs.readdir(dirPath);
for (const item of items) {
const itemPath = path.join(dirPath, item);
try {
const stats = await fs.stat(itemPath);
if (stats.isDirectory()) {
totalSize += await this.getDirectorySize(itemPath);
} else {
totalSize += stats.size;
}
} catch (itemError) {
// Skip inaccessible files/directories
logger.debug(`Cannot access ${itemPath}:`, itemError.message);
}
}
} catch (error) {
logger.debug(`Cannot read directory ${dirPath}:`, error.message);
}
return totalSize;
}
}
module.exports = MetricsCollector;
|