我正在尝试让动态更新的侧滚动线图在 rgraph 中工作。它通过对以这种格式输出数据的 php 脚本的 ajax 调用每秒更新一次:
{"cpu":28.43,"mem":75.01,"rx":0,"timestamp":1471535457240}
现在使用下面的代码,我只是想让它只处理 CPU 数据。ajax 调用每秒工作一次,但我无法更新图表。数据预先填充了 for 循环。
我究竟做错了什么?
var cpu = [], mem = [], rx = [], timestamp = [];
var dataset;
var totalPoints = 100;
var updateInterval = 1000;
var now = new Date().getTime();
var canvas = document.getElementById("cvs");
var temp = [];
// Make and draw the chart
var line = new RGraph.Line({
id: 'cvs',
data: cpu,
options: {
ymax: 100,
backgroundGridAutofitNumvlines: 10,
backgroundGridVlines: true,
backgroundGridBorder: true,
numxticks: 10,
tickmarks: true,
noaxes: false,
textSize: 12,
gutterLeft: 50,
textColor: '#aaa',
scaleZerostart: true,
textAccessible: true
}
}).draw();
function initData() {
now -= totalPoints * updateInterval;
for (var i = 0; i < totalPoints; i++) {
// temp = [now += updateInterval, 0];
cpu[i] = 0;
}
}
function GetData() {
$.ajaxSetup({ cache: false });
$.ajax({
url: "server_load.php",
dataType: 'json',
success: function (_data) {
drawGraph(_data);
},
error: function () {
setTimeout(GetData, updateInterval);
}
});
}
function drawGraph(_data) {
console.log(cpu);
cpu.shift();
var Now = _data['timestamp'];
temp = [Now, _data.cpu];
cpu.push(temp);
console.log(temp[1]);
// Reset the canvas
line.reset(document.getElementById('cvs'));
line.original_data[0] = temp[1];
line.draw();
setTimeout(GetData, updateInterval);
}
window.onload = function ()
{
initData();
GetData();
};
这是我在本地 Ubuntu 机器上运行的 php 脚本:
class serverLoad {
const OS_LINUX = "Linux";
const OS_FREEBSD = "FreeBSD";
const OS_OSX = "Darwin";
const PATH_NETSTAT = "/usr/sbin/netstat";
public $cpuLoad;
public $memoryUsed;
public $timeStamp;
public $networkBandwidth;
public $interface = 'eth0';
protected $sampleSleep = 1000000;
public function __construct()
{
$this->generateData();
}
/**
*
*/
public function generateData(){
$this->cpuLoad = $this->getServerLoad();
$this->memoryUsed = $this->getSystemMemoryInfo();
$this->networkBandwidth = $this->getNetworkBandwidth();
$this->timeStamp = $this->msTimeStamp();
$totalMemory = $this->memoryUsed['MemTotal'];
$freeMemory = $this->memoryUsed['MemTotal'] - $this->memoryUsed['MemFree'] - $this->memoryUsed['Buffers'] - $this->memoryUsed['Cached'];
$MemoryPercentage = round(($freeMemory/$totalMemory) * 100, 2) ;
$results = array('cpu' => $this->cpuLoad, 'mem' => $MemoryPercentage, 'rx' => $this->networkBandwidth['rx'], 'timestamp' => $this->timeStamp);
echo json_encode($results);
}
/**
* Returns server load in percent (just number, without percent sign)
*/
protected function getServerLoad()
{
$load = null;
if (stristr(PHP_OS, "win"))
{
$cmd = "wmic cpu get loadpercentage /all";
@exec($cmd, $output);
if ($output)
{
foreach ($output as $line)
{
if ($line && preg_match("/^[0-9]+\$/", $line))
{
$load = $line;
break;
}
}
}
}
else
{
if (is_readable("/proc/stat"))
{
// Collect 2 samples - each with 1 second period
// See: https://de.wikipedia.org/wiki/Load#Der_Load_Average_auf_Unix-Systemen
$statData1 = $this->_getServerLoadLinuxData();
usleep($this->sampleSleep);
$statData2 = $this->_getServerLoadLinuxData();
if
(
(!is_null($statData1)) &&
(!is_null($statData2))
)
{
// Get difference
$statData2[0] -= $statData1[0];
$statData2[1] -= $statData1[1];
$statData2[2] -= $statData1[2];
$statData2[3] -= $statData1[3];
// Sum up the 4 values for User, Nice, System and Idle and calculate
// the percentage of idle time (which is part of the 4 values!)
$cpuTime = $statData2[0] + $statData2[1] + $statData2[2] + $statData2[3];
// Invert percentage to get CPU time, not idle time
$load = 100 - ($statData2[3] * 100 / $cpuTime);
}
}
}
return round($load, 2);
}
/**
* Used to get the server load on linux machines
*/
protected function _getServerLoadLinuxData()
{
if (is_readable("/proc/stat"))
{
$stats = @file_get_contents("/proc/stat");
if ($stats !== false)
{
// Remove double spaces to make it easier to extract values with explode()
$stats = preg_replace("/[[:blank:]]+/", " ", $stats);
// Separate lines
$stats = str_replace(array("\r\n", "\n\r", "\r"), "\n", $stats);
$stats = explode("\n", $stats);
// Separate values and find line for main CPU load
foreach ($stats as $statLine)
{
$statLineData = explode(" ", trim($statLine));
// Found!
if
(
(count($statLineData) >= 5) &&
($statLineData[0] == "cpu")
)
{
return array(
$statLineData[1],
$statLineData[2],
$statLineData[3],
$statLineData[4],
);
}
}
}
}
return null;
}
protected function wmiWBemLocatorQuery( $query ) {
if ( class_exists( '\\COM' ) ) {
try {
$WbemLocator = new \COM( "WbemScripting.SWbemLocator" );
$WbemServices = $WbemLocator->ConnectServer( '127.0.0.1', 'root\CIMV2' );
$WbemServices->Security_->ImpersonationLevel = 3;
// use wbemtest tool to query all classes for namespace root\cimv2
return $WbemServices->ExecQuery( $query );
} catch ( \com_exception $e ) {
echo $e->getMessage();
}
} elseif ( ! extension_loaded( 'com_dotnet' ) )
trigger_error( 'It seems that the COM is not enabled in your php.ini', E_USER_WARNING );
else {
$err = error_get_last();
trigger_error( $err['message'], E_USER_WARNING );
}
return false;
}
// _dir_in_allowed_path this is your function to detect if a file is withing the allowed path (see the open_basedir PHP directive)
protected function getSystemMemoryInfo( $output_key = '' ) {
$keys = array( 'MemTotal', 'MemFree', 'MemAvailable', 'SwapTotal', 'SwapFree', 'Buffers', 'Cached' );
$result = array();
$isWin = false;
try {
// LINUX
if ( !$isWin ) {
$proc_dir = '/proc/';
$data = @file( $proc_dir . 'meminfo' );
if ( is_array( $data ) )
foreach ( $data as $d ) {
if ( 0 == strlen( trim( $d ) ) )
continue;
$d = preg_split( '/:/', $d );
$key = trim( $d[0] );
if ( ! in_array( $key, $keys ) )
continue;
$value = 1000 * floatval( trim( str_replace( ' kB', '', $d[1] ) ) );
$result[$key] = $value;
}
} else // WINDOWS
{
$wmi_found = false;
if ( $wmi_query = wmiWBemLocatorQuery(
"SELECT FreePhysicalMemory,FreeVirtualMemory,TotalSwapSpaceSize,TotalVirtualMemorySize,TotalVisibleMemorySize FROM Win32_OperatingSystem" ) ) {
foreach ( $wmi_query as $r ) { // TODO add Buffers and cached to this loop
$result['MemFree'] = $r->FreePhysicalMemory * 1024;
$result['MemAvailable'] = $r->FreeVirtualMemory * 1024;
$result['SwapFree'] = $r->TotalSwapSpaceSize * 1024;
$result['SwapTotal'] = $r->TotalVirtualMemorySize * 1024;
$result['MemTotal'] = $r->TotalVisibleMemorySize * 1024;
$wmi_found = true;
}
}
// TODO a backup implementation using the $_SERVER array
}
} catch ( Exception $e ) {
echo $e->getMessage();
}
return empty( $output_key ) || ! isset( $result[$output_key] ) ? $result : $result[$output_key];
}
/**
* Returns network bandwidth usage
*/
protected function getNetworkBandwidth(){
$rx[] = $this->getInterfaceReceivedBytes($this->interface);
$tx[] = $this->getInterfaceSentBytes($this->interface);
usleep($this->sampleSleep);
$rx[] = $this->getInterfaceReceivedBytes($this->interface);
$tx[] = $this->getInterfaceSentBytes($this->interface);
$tbps = $tx[1] - $tx[0];
$rbps = $rx[1] - $rx[0];
//convert to kbps
$bandwidth['rx'] = round(($rbps * 8) / 1000, 2);
$bandwidth['tx'] = round(($tbps * 8) / 1000, 2);
return $bandwidth;
}
protected function getInterfaceReceivedBytes($interface)
{
if ($this->isLinux()) {
$filepath = '/sys/class/net/%s/statistics/rx_bytes';
$output = file_get_contents(sprintf($filepath, $interface));
return $output;
}
if ($this->isFreeBSD() || $this->isOSX()) {
$command = "%s -ibn| grep %s | grep Link | awk '{print $7}'";
exec(sprintf($command, PATH_NETSTAT, $interface), $output);
return array_shift($output);
}
throw new Exception('Unable to guess OS');
}
protected function getInterfaceSentBytes($interface)
{
if ($this->isLinux()) {
$filepath = '/sys/class/net/%s/statistics/tx_bytes';
$output = file_get_contents(sprintf($filepath, $interface));
return $output;
}
if ($this->isFreeBSD() || $this->isOSX()) {
$command = "%s -ibn| grep %s | grep Link | awk '{print $10}'";
exec(sprintf($command, PATH_NETSTAT, $interface), $output);
return array_shift($output);
}
throw new Exception('Unable to guess OS');
}
protected function isOSX()
{
$uname = explode(' ', php_uname());
return $uname[0] === self::OS_OSX;
}
protected function isLinux()
{
$uname = explode(' ', php_uname());
return $uname[0] === self::OS_LINUX;
}
protected function isFreeBSD()
{
$uname = explode(' ', php_uname());
return $uname[0] === self::OS_FREEBSD;
}
/**
* Returns current unix timestamp
*/
protected function msTimeStamp() {
return round(microtime(1) * 1000);
}
}
$data = new serverLoad();
我还设置了一个 jsfiddle,但不确定如何使用 ajax 调用: http: //fiddle.jshell.net/Vbgkk/18/