From 807f80da94713bc109ae2ef2c44bb5f62463b304 Mon Sep 17 00:00:00 2001 From: frytimo Date: Fri, 27 Jun 2025 18:25:32 -0300 Subject: [PATCH] Update dashboard with cpu status websockets (#7400) * Remove setting hardcoded timer * Use websockets for real-time CPU status on dashboard * Add system_dashboard service file * moved javascript file to core --- .../resources/dashboard/system_cpu_status.php | 59 ++++++------ .../resources/dashboard/system_status.php | 93 ++++++++++++++----- .../services/debian-system_dashboard.service | 33 +++++++ core/dashboard/index.php | 4 + .../resources/javascript/ws_client.js | 0 .../classes/base_websocket_system_service.php | 2 - 6 files changed, 138 insertions(+), 53 deletions(-) create mode 100644 app/system/resources/services/debian-system_dashboard.service rename app/system/resources/javascript/websocket_client.js => core/dashboard/resources/javascript/ws_client.js (100%) diff --git a/app/system/resources/dashboard/system_cpu_status.php b/app/system/resources/dashboard/system_cpu_status.php index 34c5106aff..41919d9f7a 100644 --- a/app/system/resources/dashboard/system_cpu_status.php +++ b/app/system/resources/dashboard/system_cpu_status.php @@ -60,39 +60,38 @@ subscriber::save_token($token, [system_dashboard_service::get_service_name()]); - //break the caching with version - $version = md5(file_get_contents(__DIR__, '/resources/javascript/websocket_client.js')); - - //set script source - echo "\n"; - //add half doughnut chart if (!isset($dashboard_chart_type) || $dashboard_chart_type == "doughnut"): ?>
\n"; echo "".$text['label-cpu_usage']."\n"; - echo "".$percent_cpu."%\n"; + echo "".$percent_cpu."%\n"; echo "\n"; $c = ($c) ? 0 : 1; } diff --git a/app/system/resources/dashboard/system_status.php b/app/system/resources/dashboard/system_status.php index 90ab835233..459977a962 100644 --- a/app/system/resources/dashboard/system_status.php +++ b/app/system/resources/dashboard/system_status.php @@ -63,12 +63,61 @@ $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; } } } +//include websocket real-time updates + $token = (new token())->create($_SERVER['PHP_SELF']); + echo " \n"; + subscriber::save_token($token, [system_dashboard_service::get_service_name()]); +?> + +\n"; @@ -137,7 +186,7 @@ if ($dashboard_row_span > 1) { echo " ".$text['label-processor_usage']."\n"; echo "
\n"; - echo "
get('theme', 'dashboard_cpu_usage_chart_main_color') ?? '#03c04a').";'>".($percent_cpu > 100 ? 100 : round($percent_cpu))."%
\n"; + echo "
get('theme', 'dashboard_cpu_usage_chart_main_color') ?? '#03c04a').";'>".($percent_cpu > 100 ? 100 : round($percent_cpu))."%
\n"; echo "
\n"; echo "
 
\n"; } @@ -185,15 +234,15 @@ 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 "".$text['label-os_version']."\n"; @@ -224,18 +273,18 @@ 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 "".$text['label-memory_usage']."\n"; echo "".$percent_memory."% (".$used_h." / ".$total_h.")"."\n"; @@ -250,10 +299,10 @@ 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); @@ -262,7 +311,7 @@ // Set style color based on thresholds $style = ($percent_swap > 90) ? "color: red;" : (($percent_swap > 75) ? "color: orange;" : ""); - + echo "\n"; echo "".$text['label-swap_usage']."\n"; echo "".$percent_swap."% (".$swap_used_h." / ".$swap_total_h.")"."\n"; @@ -274,11 +323,11 @@ //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 "".$text['label-disk_usage']."\n"; echo "".$percent_disk_usage."% (".$used_space." / ".$total_space.")"."\n"; @@ -305,30 +354,30 @@ $connections = sizeof($tmp) - 1; } } - + if (!empty($sql_current) && !empty($sql_max)) { if (!isset($database)) { $database = new database; } - + // 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 + $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 "" . $text['label-database_connections'] . "\n"; echo "" . $connections . "\n"; diff --git a/app/system/resources/services/debian-system_dashboard.service b/app/system/resources/services/debian-system_dashboard.service new file mode 100644 index 0000000000..c00092af30 --- /dev/null +++ b/app/system/resources/services/debian-system_dashboard.service @@ -0,0 +1,33 @@ +; Author: Mark J Crane +; cp /var/www/fusionpbx/app/system/resources/service/debian.service /etc/systemd/system/system_dashboard.service +; systemctl daemon-reload +; systemctl enable --now system_dashboard + +[Unit] +Description=FusionPBX System Dashboard Information Service +Wants=network-online.target +Requires=network.target local-fs.target +;Requires=network.target local-fs.target postgresql.service +After=network.target network-online.target local-fs.target +;After=network.target network-online.target local-fs.target postgresql.service +StartLimitIntervalSec=0 + +[Service] +Type=simple +;Type=forking +PIDFile=/var/run/fusionpbx/system_dashboard.pid +WorkingDirectory=/var/www/fusionpbx +;Environment="USER=www-data" +;Environment="GROUP=www-data" +;EnvironmentFile=-/etc/default/fusionpbx +ExecStartPre=/bin/mkdir -p /var/run/fusionpbx +;ExecStartPre=/bin/chown -R ${USER}:${GROUP} /var/www/fusionpbx +ExecStart=/usr/bin/php /var/www/fusionpbx/app/system/resources/service/system.php --no-fork +User=www-data +Group=www-data +TimeoutSec=55s +Restart=always + +[Install] +WantedBy=multi-user.target +Also= diff --git a/core/dashboard/index.php b/core/dashboard/index.php index 60feaad13c..931912fd8d 100644 --- a/core/dashboard/index.php +++ b/core/dashboard/index.php @@ -171,6 +171,10 @@ $document['title'] = $text['title-dashboard']; require_once "resources/header.php"; +//include websockets + $version = md5(file_get_contents(__DIR__, '/resources/javascript/ws_client.js')); + echo "\n"; + //include sortablejs echo ""; diff --git a/app/system/resources/javascript/websocket_client.js b/core/dashboard/resources/javascript/ws_client.js similarity index 100% rename from app/system/resources/javascript/websocket_client.js rename to core/dashboard/resources/javascript/ws_client.js diff --git a/core/websockets/resources/classes/base_websocket_system_service.php b/core/websockets/resources/classes/base_websocket_system_service.php index 8e891bb7ff..369db33d36 100644 --- a/core/websockets/resources/classes/base_websocket_system_service.php +++ b/core/websockets/resources/classes/base_websocket_system_service.php @@ -142,8 +142,6 @@ abstract class base_websocket_system_service extends service implements websocke // Timers can be set by child classes if ($this->timer_expire_time !== null && time() >= $this->timer_expire_time) { $this->on_timer(); - // Set another timer to fire again - $this->set_timer(3); } } return 0;