diff --git a/api/index.js b/api/index.js index 9acd039..cc192cb 100644 --- a/api/index.js +++ b/api/index.js @@ -4500,15 +4500,30 @@ function updateStatsFromCpuMonitoringEvent(monitoringData) { updateStatsCell('memory-usage', monitoringData.memory_usage_mb.toFixed(1) + ' MB'); } + // MEM% bar using memory_percent from server + if (monitoringData.memory_percent !== undefined) { + const memPct = Math.min(100, Math.max(0, monitoringData.memory_percent)); + updateStatsCell('memory-usage', monitoringData.memory_usage_mb.toFixed(1) + ' MB ' + makeAsciiBar(memPct)); + } + if (monitoringData.current_cpu_core !== undefined) { updateStatsCell('cpu-core', 'Core ' + monitoringData.current_cpu_core); } - // Calculate CPU usage percentage if we have the data + // CPU% using delta between samples if (monitoringData.process_cpu_time !== undefined && monitoringData.system_cpu_time !== undefined) { - // For now, just show the raw process CPU time (simplified) - // In a real implementation, you'd calculate deltas over time - updateStatsCell('cpu-usage', monitoringData.process_cpu_time + ' ticks'); + if (window._prevCpuSample) { + const procDelta = monitoringData.process_cpu_time - window._prevCpuSample.proc; + const sysDelta = monitoringData.system_cpu_time - window._prevCpuSample.sys; + if (sysDelta > 0) { + const cpuPct = Math.min(100, Math.max(0, (procDelta / sysDelta) * 100)); + updateStatsCell('cpu-usage', makeAsciiBar(cpuPct)); + } + } + window._prevCpuSample = { + proc: monitoringData.process_cpu_time, + sys: monitoringData.system_cpu_time + }; } } catch (error) { @@ -4898,6 +4913,13 @@ function formatTimestamp(timestamp) { return date.toLocaleString(); } +// Generate ASCII progress bar: [###############.....] 75% +function makeAsciiBar(pct) { + const filled = Math.round(pct / 5); // 20 chars = 100% + const empty = 20 - filled; + return '[' + '#'.repeat(filled) + '.'.repeat(empty) + '] ' + pct.toFixed(1) + '%'; +} + // Update statistics cell with flash animation if value changed function updateStatsCell(cellId, newValue) { const cell = document.getElementById(cellId); diff --git a/relay.pid b/relay.pid index 84bc9e5..218a2ab 100644 --- a/relay.pid +++ b/relay.pid @@ -1 +1 @@ -2380224 +2388377 diff --git a/src/api.c b/src/api.c index e088cb2..bfee576 100644 --- a/src/api.c +++ b/src/api.c @@ -1295,13 +1295,13 @@ cJSON* query_cpu_metrics(void) { // Get active WebSocket connection count cJSON_AddNumberToObject(cpu_stats, "active_connections", (double)get_active_connection_count()); - // Get memory usage from /proc/self/status + // Get memory usage from /proc/self/status and calculate MEM% + unsigned long rss_kb = 0; FILE* mem_stat = fopen("/proc/self/status", "r"); if (mem_stat) { char line[256]; while (fgets(line, sizeof(line), mem_stat)) { if (strncmp(line, "VmRSS:", 6) == 0) { - unsigned long rss_kb; if (sscanf(line, "VmRSS: %lu kB", &rss_kb) == 1) { double rss_mb = rss_kb / 1024.0; cJSON_AddNumberToObject(cpu_stats, "memory_usage_mb", rss_mb); @@ -1312,6 +1312,25 @@ cJSON* query_cpu_metrics(void) { fclose(mem_stat); } + // Get total system memory from /proc/meminfo for MEM% + if (rss_kb > 0) { + FILE* meminfo = fopen("/proc/meminfo", "r"); + if (meminfo) { + char line[256]; + while (fgets(line, sizeof(line), meminfo)) { + if (strncmp(line, "MemTotal:", 9) == 0) { + unsigned long total_kb; + if (sscanf(line, "MemTotal: %lu kB", &total_kb) == 1 && total_kb > 0) { + double mem_pct = (rss_kb * 100.0) / total_kb; + cJSON_AddNumberToObject(cpu_stats, "memory_percent", mem_pct); + } + break; + } + } + fclose(meminfo); + } + } + return cpu_stats; } diff --git a/src/main.h b/src/main.h index 9276b0d..1f4612b 100644 --- a/src/main.h +++ b/src/main.h @@ -13,8 +13,8 @@ // Using CRELAY_ prefix to avoid conflicts with nostr_core_lib VERSION macros #define CRELAY_VERSION_MAJOR 1 #define CRELAY_VERSION_MINOR 2 -#define CRELAY_VERSION_PATCH 47 -#define CRELAY_VERSION "v1.2.47" +#define CRELAY_VERSION_PATCH 48 +#define CRELAY_VERSION "v1.2.48" // Relay metadata (authoritative source for NIP-11 information) #define RELAY_NAME "C-Relay"