From b5cf6f1690e014cc5c24e94adff52c352043beb0 Mon Sep 17 00:00:00 2001 From: n0obHere <156116672+n0obHere@users.noreply.github.com> Date: Mon, 12 May 2025 12:44:40 -0400 Subject: [PATCH] Enhanced dashboard system_status card with more useful system info (#7366) * Update system_status.php Adjust column width to make some overflowing multi-line values into one-line view. * Enhanced dashboard system_status card with more useful system info - Added OS version detection - Fixed not working memory usage with format (60% (1G/2G)) - Replaced memory available with swap usage - Improved disk usage display format (57% (12G/20G)) - Added DB max connections display (Current/Max) * Added style colors based on thresholds * Update app_languages.php Additional languages for new system_status items --- .../resources/dashboard/system_status.php | 143 ++++++++++++++---- core/user_settings/app_languages.php | 54 +++++++ 2 files changed, 167 insertions(+), 30 deletions(-) diff --git a/app/system/resources/dashboard/system_status.php b/app/system/resources/dashboard/system_status.php index 49f37f4d85..90ab835233 100644 --- a/app/system/resources/dashboard/system_status.php +++ b/app/system/resources/dashboard/system_status.php @@ -54,10 +54,16 @@ //disk usage if (PHP_OS == 'FreeBSD' || PHP_OS == 'Linux') { - $tmp = shell_exec("df / 2>&1"); + $tmp = shell_exec("df -h / 2>&1"); // Added -h for human-readable sizes $tmp = explode("\n", $tmp); $tmp = preg_replace('!\s+!', ' ', $tmp[1]); // multiple > single space $tmp = explode(' ', $tmp); + + // Extract values (columns may vary slightly by OS) + $used_space = $tmp[2] ?? '-'; + $total_space = $tmp[1] ?? '-'; + $percent_disk_usage = ''; + foreach ($tmp as $stat) { if (substr_count($stat, '%') > 0) { $percent_disk_usage = rtrim($stat,'%'); break; } } @@ -161,7 +167,7 @@ echo "
"; echo "\n"; echo "\n"; - echo "\n"; + echo "\n"; echo "\n"; echo "\n"; @@ -172,6 +178,31 @@ echo "\n"; $c = ($c) ? 0 : 1; + // OS Type and Version (for Linux) + if (stristr(PHP_OS, 'Linux')) { + // Try to get pretty OS name + $os_info = ''; + if (file_exists('/etc/os-release')) { + $os_release = parse_ini_file('/etc/os-release'); + $os_info = $os_release['PRETTY_NAME'] ?? ''; + } + // Fallback to basic uname info + elseif (function_exists('php_uname')) { + $os_info = php_uname('s') . ' ' . php_uname('r'); // e.g. "Linux 5.10.0" + } + + // Clean up the output + $os_info = str_replace('"', '', $os_info); // Remove quotes if present + + if (!empty($os_info)) { + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + $c = ($c) ? 0 : 1; + } + } + //os uptime if (stristr(PHP_OS, 'Linux')) { $prefix = 'up '; @@ -186,39 +217,71 @@ } } - //memory usage (for available memory, use "free | awk 'FNR == 3 {print $4/($3+$4)*100}'" instead) + //memory usage if (stristr(PHP_OS, 'Linux')) { - $free = shell_exec("/usr/bin/which free"); - $awk = shell_exec("/usr/bin/which awk"); - $percent_memory = round((float)shell_exec(escapeshellcmd($free." | ".$awk." 'FNR == 3 {print $3/($3+$4)*100}'")), 1); - if (!empty($percent_memory)) { + // Get memory usage percentage + $meminfo = shell_exec('free -b | grep Mem'); + if (!empty($meminfo)) { + $meminfo = preg_replace('/\s+/', ' ', trim($meminfo)); + $parts = explode(' ', $meminfo); + + $total = $parts[1]; + $used = $parts[2]; + $percent_memory = round(($used / $total) * 100, 1); + + // Set style color based on thresholds + $style = ($percent_memory > 90) ? "color: red;" : (($percent_memory > 75) ? "color: orange;" : ""); + + // Format with used/total (e.g. "40% (3.2G/8G)") + $total_h = round($total / (1024*1024*1024), 1) . 'G'; + $used_h = round($used / (1024*1024*1024), 1) . 'G'; + echo "\n"; echo "\n"; - echo "\n"; + echo "\n"; echo "\n"; $c = ($c) ? 0 : 1; } } - //memory available + //swap usage if (stristr(PHP_OS, 'Linux')) { - $result = trim(shell_exec('free -hw | grep \'Mem:\' | cut -d\' \' -f 55-64')); - if (!empty($result)) { - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - $c = ($c) ? 0 : 1; + $swapinfo = shell_exec('free -b | grep Swap'); + if (!empty($swapinfo)) { + $swapinfo = preg_replace('/\s+/', ' ', trim($swapinfo)); + $parts = explode(' ', $swapinfo); + + $swap_total = $parts[1]; + $swap_used = $parts[2]; + + // Only show swap if it exists (total > 0) + if ($swap_total > 0) { + $percent_swap = round(($swap_used / $swap_total) * 100, 1); + $swap_total_h = round($swap_total / (1024*1024*1024), 1) . 'G'; + $swap_used_h = round($swap_used / (1024*1024*1024), 1) . 'G'; + + // Set style color based on thresholds + $style = ($percent_swap > 90) ? "color: red;" : (($percent_swap > 75) ? "color: orange;" : ""); + + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + $c = ($c) ? 0 : 1; + } } } - //disk usage - if (stristr(PHP_OS, 'Linux')) { - //calculated above - if (!empty($percent_disk_usage)) { + //disk usage display + if (stristr(PHP_OS, 'Linux') || stristr(PHP_OS, 'FreeBSD')) { + + if (!empty($percent_disk_usage) && $used_space != '-' && $total_space != '-') { + // Set style color based on thresholds + $style = ($percent_disk_usage > 90) ? "color: red;" : (($percent_disk_usage > 75) ? "color: orange;" : ""); + echo "\n"; echo "\n"; - echo "\n"; + echo "\n"; echo "\n"; $c = ($c) ? 0 : 1; } @@ -227,28 +290,48 @@ //db connections switch ($db_type) { case 'pgsql': - $sql = "select count(*) from pg_stat_activity"; + $sql_current = "SELECT count(*) FROM pg_stat_activity"; + $sql_max = "SHOW max_connections"; break; case 'mysql': - $sql = "show status where `variable_name` = 'Threads_connected'"; + $sql_current = "SHOW STATUS WHERE `variable_name` = 'Threads_connected'"; + $sql_max = "SHOW VARIABLES LIKE 'max_connections'"; break; default: - unset($sql); + unset($sql_current, $sql_max); if (!empty($db_path) && !empty($dbfilename)) { - $tmp = shell_exec("lsof ".realpath($db_path).'/'.$dbfilename); + $tmp = shell_exec("lsof " . realpath($db_path) . '/' . $dbfilename); $tmp = explode("\n", $tmp); $connections = sizeof($tmp) - 1; } } - if (!empty($sql)) { + + if (!empty($sql_current) && !empty($sql_max)) { if (!isset($database)) { $database = new database; } - $connections = $database->select($sql, null, 'column'); - unset($sql); + + // Get current connections + $current_connections = $database->select($sql_current, null, 'column'); + + // Get max connections (handles both PostgreSQL & MySQL) + $max_result = $database->select($sql_max, null, ($db_type == 'pgsql') ? 'column' : 'row'); + $max_connections = ($db_type == 'mysql') ? $max_result['Value'] : $max_result; + + // Format as "current/max" + $connections = ($current_connections !== false && $max_connections !== false) + ? "Current: " . $current_connections . ", Max: " . $max_connections + : "N/A"; + + unset($sql_current, $sql_max); } + if (!empty($connections)) { + // Set style color based on thresholds + $ratio = $current_connections / $max_connections; + $style = ($ratio > 0.9) ? "color: red;" : (($ratio > 0.75) ? "color: orange;" : ""); + echo "\n"; - echo "\n"; - echo "\n"; + echo "\n"; + echo "\n"; echo "\n"; $c = ($c) ? 0 : 1; } diff --git a/core/user_settings/app_languages.php b/core/user_settings/app_languages.php index cd50ff5bd3..bf3defed93 100644 --- a/core/user_settings/app_languages.php +++ b/core/user_settings/app_languages.php @@ -1675,6 +1675,60 @@ $text['label-memory_available']['zh-cn'] = "有效内存"; $text['label-memory_available']['ja-jp'] = "使用可能なメモリ"; $text['label-memory_available']['ko-kr'] = "사용 가능한 메모리"; +$text['label-swap_usage']['en-us'] = "Swap Usage"; +$text['label-swap_usage']['en-gb'] = "Swap Usage"; +$text['label-swap_usage']['ar-eg'] = ""; +$text['label-swap_usage']['de-at'] = ""; +$text['label-swap_usage']['de-ch'] = ""; +$text['label-swap_usage']['de-de'] = ""; +$text['label-swap_usage']['el-gr'] = ""; +$text['label-swap_usage']['es-cl'] = ""; +$text['label-swap_usage']['es-mx'] = ""; +$text['label-swap_usage']['fr-ca'] = ""; +$text['label-swap_usage']['fr-fr'] = ""; +$text['label-swap_usage']['he-il'] = ""; +$text['label-swap_usage']['it-it'] = ""; +$text['label-swap_usage']['ka-ge'] = ""; +$text['label-swap_usage']['nl-nl'] = ""; +$text['label-swap_usage']['pl-pl'] = ""; +$text['label-swap_usage']['pt-br'] = ""; +$text['label-swap_usage']['pt-pt'] = ""; +$text['label-swap_usage']['ro-ro'] = ""; +$text['label-swap_usage']['ru-ru'] = ""; +$text['label-swap_usage']['sv-se'] = ""; +$text['label-swap_usage']['tr-tr'] = ""; +$text['label-swap_usage']['uk-ua'] = ""; +$text['label-swap_usage']['zh-cn'] = ""; +$text['label-swap_usage']['ja-jp'] = ""; +$text['label-swap_usage']['ko-kr'] = ""; + +$text['label-os_version']['en-us'] = "OS Version"; +$text['label-os_version']['en-gb'] = "OS Version"; +$text['label-os_version']['ar-eg'] = ""; +$text['label-os_version']['de-at'] = ""; +$text['label-os_version']['de-ch'] = ""; +$text['label-os_version']['de-de'] = ""; +$text['label-os_version']['el-gr'] = ""; +$text['label-os_version']['es-cl'] = ""; +$text['label-os_version']['es-mx'] = ""; +$text['label-os_version']['fr-ca'] = ""; +$text['label-os_version']['fr-fr'] = ""; +$text['label-os_version']['he-il'] = ""; +$text['label-os_version']['it-it'] = ""; +$text['label-os_version']['ka-ge'] = ""; +$text['label-os_version']['nl-nl'] = ""; +$text['label-os_version']['pl-pl'] = ""; +$text['label-os_version']['pt-br'] = ""; +$text['label-os_version']['pt-pt'] = ""; +$text['label-os_version']['ro-ro'] = ""; +$text['label-os_version']['ru-ru'] = ""; +$text['label-os_version']['sv-se'] = ""; +$text['label-os_version']['tr-tr'] = ""; +$text['label-os_version']['uk-ua'] = ""; +$text['label-os_version']['zh-cn'] = ""; +$text['label-os_version']['ja-jp'] = ""; +$text['label-os_version']['ko-kr'] = ""; + $text['label-lowercase_letters']['en-us'] = "Lowercase Letters"; $text['label-lowercase_letters']['en-gb'] = "Lowercase Letters"; $text['label-lowercase_letters']['ar-eg'] = "أحرف صغيرة";
".$text['label-item']."".$text['label-item']."".$text['label-value']."