From 31ea2ca2c8896e26316ddb11dd673599a42639b1 Mon Sep 17 00:00:00 2001 From: Tyron Madlener Date: Fri, 1 Jul 2011 10:55:52 +0200 Subject: [PATCH] CPU, Memory and SWAP Usage charts for Windows and Linux --- js/server_status.js | 75 ++++++++++++++++- libraries/sysinfo.lib.php | 106 ++++++++++++++++++++++++ server_status.php | 53 +++++++++--- themes/pmahomme/css/theme_right.css.php | 4 +- 4 files changed, 220 insertions(+), 18 deletions(-) create mode 100644 libraries/sysinfo.lib.php diff --git a/js/server_status.js b/js/server_status.js index 3bcbdb8d25..3a7141ef58 100644 --- a/js/server_status.js +++ b/js/server_status.js @@ -567,6 +567,10 @@ $(function() { 'Add chart to grid': function() { if(newChart.nodes.length == 0) return; + var type = $('input[name="chartType"]').find(':checked').val(); + if(type=='cpu' || type='memory'); + newChart = presetCharts[type + '-' + server_os]; + newChart.title = $('input[name="chartTitle"]').attr('value'); // Add a cloned object to the chart grid addChart($.extend(true, {}, newChart)); @@ -585,6 +589,10 @@ $(function() { return false; }); + $('input[name="chartType"]').change(function() { + $('#chartVariableSettings').toggle(this.checked && this.value == 'variable'); + }); + $('input[name="useDivisor"]').change(function() { $('span.divisorInput').toggle(this.checked); }); @@ -626,6 +634,8 @@ $(function() { display: $('input[name="differentialValue"]').attr('checked') ? 'differential' : '', }; + if(serie.name = 'Processes') serie.dataType='proc'; + if($('input[name="useDivisor"]').attr('checked')) serie.valueDivisor = parseInt($('input[name="valueDivisor"]').attr('value')); @@ -668,18 +678,72 @@ $(function() { var chartSize = { width: 300, height: 300 }; + var presetCharts = { + 'cpu-WINNT': { + title: 'System CPU Usage', + nodes: [{ dataType: 'cpu', name: 'loadavg'}] + }, + 'memory-WINNT': { + title: 'System memory (MiB)', + nodes: [ + { dataType: 'memory', name: 'MemTotal', valueDivisor: 1024 }, + { dataType: 'memory', name: 'MemFree', valueDivisor: 1024 }, + ] + }, + 'swap-WINNT': { + title: 'System swap (MiB)', + nodes: [ + { dataType: 'memory', name: 'SwapTotal', valueDivisor: 1024 }, + { dataType: 'memory', name: 'SwapUsed', valueDivisor: 1024 }, + ] + }, + 'cpu-Linux': { + title: 'System CPU Usage', + nodes: [ + { dataType: 'cpu', + name: 'none', + transformFn: function(cur, prev) { + var diff_total = cur.busy + cur.idle - (prev.busy + prev.idle); + var diff_idle = cur.idle - prev.idle; + return 100*(diff_total - diff_idle) / diff_total; + } + } + ] + }, + 'memory-Linux': { + title: 'System memory (in MiB)', + nodes: [ + { dataType: 'memory', name: 'MemTotal', valueDivisor: 1024 }, + { dataType: 'memory', name: 'MemCached', valueDivisor: 1024 }, + { dataType: 'memory', name: 'MemFree', valueDivisor: 1024 }, + { dataType: 'memory', name: 'Buffers', valueDivisor: 1024 }, + ] + }, + 'swap-Linux': { + title: 'System swap (in MiB)', + nodes: [ + { dataType: 'memory', name: 'SwapTotal', valueDivisor: 1024 }, + { dataType: 'memory', name: 'SwapCached', valueDivisor: 1024 }, + { dataType: 'memory', name: 'SwapFree', valueDivisor: 1024 }, + ] + } + } + // Default setting chartGrid = { - '0': { title: 'Questions', + '0': presetCharts['cpu-'+server_os], + '1': presetCharts['memory-'+server_os], + '2': presetCharts['swap-'+server_os], + '3': { title: 'Questions', nodes: [{ dataType:'statusvar', name:'Questions', display: 'differential'}] }, - '1': { + '4': { title: 'Connections / Processes', nodes: [ { dataType:'statusvar', name:'Connections', display: 'differential'}, - { dataType:'other', name:'Processes'} + { dataType:'proc', name:'Processes'} ] }, - '2': { + '5': { title: 'Traffic (in KiB)', nodes: [ { dataType:'statusvar', name: 'Bytes_sent', display: 'differential', valueDivisor: 1024}, @@ -797,6 +861,9 @@ $(function() { } if(elem.nodes[j].valueDivisor) value = value / elem.nodes[j].valueDivisor; + + if(elem.nodes[j].transformFn) + value = elem.nodes[j].transformFn(chartData[key][j],oldChartData[key][j],j); elem.chart.series[j].addPoint( { x: chartData.x, y: value }, diff --git a/libraries/sysinfo.lib.php b/libraries/sysinfo.lib.php new file mode 100644 index 0000000000..e18f4f386d --- /dev/null +++ b/libraries/sysinfo.lib.php @@ -0,0 +1,106 @@ +_wmi = $objLocator->ConnectServer(); + } + + function loadavg() { + $loadavg = ""; + $sum = 0; + $buffer = $this->_getWMI('Win32_Processor', array('LoadPercentage')); + + foreach ($buffer as $load) { + $value = $load['LoadPercentage']; + $loadavg .= $value.' '; + $sum += $value; + } + + return array('loadavg' => $sum / count($buffer)); + } + + private function _getWMI($strClass, $strValue = array()) { + $arrData = array(); + $value = ""; + + $objWEBM = $this->_wmi->Get($strClass); + $arrProp = $objWEBM->Properties_; + $arrWEBMCol = $objWEBM->Instances_(); + foreach ($arrWEBMCol as $objItem) { + if (is_array($arrProp)) { + reset($arrProp); + } + $arrInstance = array(); + foreach ($arrProp as $propItem) { + if ( empty($strValue)) { + eval("\$value = \$objItem->".$propItem->Name.";"); + $arrInstance[$propItem->Name] = trim($value); + } else { + if (in_array($propItem->Name, $strValue)) { + eval("\$value = \$objItem->".$propItem->Name.";"); + $arrInstance[$propItem->Name] = trim($value); + } + } + } + $arrData[] = $arrInstance; + } + return $arrData; + } + + + function memory() { + $buffer = $this->_getWMI("Win32_OperatingSystem", array('TotalVisibleMemorySize', 'FreePhysicalMemory')); + $mem = Array(); + $mem['MemTotal'] = $buffer[0]['TotalVisibleMemorySize']; + $mem['MemFree'] = $buffer[0]['FreePhysicalMemory']; + // $mem['setMemUsed'] = $mem['setMemTotal'] - $mem['setMemFree']; + + $buffer = $this->_getWMI('Win32_PageFileUsage'); + + $mem['SwapTotal'] = 0; + $mem['SwapUsed'] = 0; + $mem['SwapPeak'] = 0; + + foreach ($buffer as $swapdevice) { + $mem['SwapTotal'] += $swapdevice['AllocatedBaseSize'] * 1024; + $mem['SwapUsed'] += $swapdevice['CurrentUsage'] * 1024; + $mem['SwapPeak'] += $swapdevice['PeakUsage'] * 1024; + } + + return $mem; + } +} + +class Linux { + public $os = 'Linux'; + + function loadavg() { + $buf = file_get_contents('/proc/stat'); + $nums=preg_split("/\s+/", substr($buf,0,strpos($buf,"\n"))); + return Array('busy' => $nums[1]+$nums[2]+$num[3], 'idle' => $nums[4]); + } + + function memory() { + preg_match_all('/^(MemTotal|MemFree|Cached|Buffers|SwapCached|SwapTotal|SwapFree):\s+(.*)\s*kB/im', file_get_contents('/proc/meminfo'), $matches); + + return array_combine( $matches[1], $matches[2] ); + } +} diff --git a/server_status.php b/server_status.php index bf490c9f20..950b6d358c 100644 --- a/server_status.php +++ b/server_status.php @@ -73,6 +73,7 @@ if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) { case 'chartgrid': $ret = json_decode($_REQUEST['requiredData'],true); $statusVars = Array(); + $sysinfo = $loadavg = $memory = 0; foreach($ret as $chart_id=>$chartNodes) { foreach($chartNodes as $node_id=>$node) { @@ -80,11 +81,32 @@ if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) { case 'statusvar': $statusVars[] = $node['name']; break; - case 'other': - if($node['name']=='Processes') { - $result = PMA_DBI_query('SHOW PROCESSLIST'); - $ret[$chart_id][$node_id]['y'] = PMA_DBI_num_rows($result); + + case 'proc': + $result = PMA_DBI_query('SHOW PROCESSLIST'); + $ret[$chart_id][$node_id]['y'] = PMA_DBI_num_rows($result); + break; + + case 'cpu': + if(! $sysinfo) { + require_once('libraries/sysinfo.lib.php'); + $sysinfo = getSysInfo(); } + if(! $loadavg) + $loadavg = $sysinfo->loadavg(); + + $ret[$chart_id][$node_id]['y'] = $loadavg[$node['name']]; + break; + + case 'memory': + if(! $sysinfo) { + require_once('libraries/sysinfo.lib.php'); + $sysinfo = getSysInfo(); + } + if(! $memory) + $memory = $sysinfo->memory(); + + $ret[$chart_id][$node_id]['y'] = $memory[$node['name']]; break; } } @@ -403,6 +425,7 @@ pma_token = ''; url_query = ''; pma_theme_image = ''; server_time_diff = new Date().getTime() - ; +server_os = '';

  • -
  • +
  • @@ -539,13 +562,15 @@ echo __('Runtime Information');