<?php
/*
RRD4SAR
Description: Fetch SAR statistics for a selected day for a selected remote machine and display them graphically. Uses RRDtool (Copyright 1997-2004 by Tobias Oetiker ), SAR command authored by Sebastien Godard & PHP(libssh2).
License: Distributed under GNU GENERAL PUBLIC LICENSE - Version 3
Author: Praveen Kumar K S
Download: http://www.chakravaka.com/rrd4sar/rrd4sar.tar.gz)
Copyright (C) 2010 Praveen Kumar K S
This file is part RRD4SAR.
RRD4SAR program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class sarPoller {
function sarPoller($rrd4sar_ini,$hosts_ini)
{
$this->cwd=getcwd();
$this->rrd4sar=parse_ini_file($rrd4sar_ini, true);
$this->configs=$this->rrd4sar["configs"];
$this->units=$this->rrd4sar["units"];
$this->hosts=parse_ini_file($hosts_ini, true);
}
function sshExec($p_cmd)
{
$connection = ssh2_connect($this->host,$this->hostarr["ssh_port"]);
ssh2_auth_password($connection,$this->hostarr["ssh_user"],$this->hostarr["ssh_pass"]);
$stream=ssh2_exec($connection,$p_cmd);
stream_set_blocking($stream,true);
$l_res_arr=array();
if($stream)
{
while(!feof($stream))
{
$l_str=fgets($stream,4096);
if(empty($l_str))
{
break;
}
array_push($l_res_arr,$l_str);
}
}
stream_set_blocking($stream,false);
if(!empty($l_res_arr))
{
return $l_res_arr;
} else {
return false;
}
}
function sarFileExists($l_sarfile)
{
$l_cmd="ls $l_sarfile";
$l_sarexists=$this->sshExec($l_cmd);
if($l_sarexists)
{
return true;
} else {
return false;
}
}
function getCPUMetrics()
{
$l_cmd=$this->base_cmd;
$l_cpu_metrics=$this->sshExec($l_cmd);
if($l_cpu_metrics)
{
$l_consider=false;
foreach($l_cpu_metrics as $l_line)
{
if(ereg("Average",$l_line))
{
break;
}
if($l_consider)
{
list($l_time,$l_time_ampm,,$l_user,$l_nice,$l_system,$l_iowait)=sscanf($l_line,"%s %s %s %f %f %f %f");
if ($l_time_ampm=="AM" && preg_match("/^12:/",$l_time))
{
$l_tstamp=strtotime($l_time)-"43200";
} elseif($l_time_ampm=="AM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time);
} elseif($l_time_ampm=="PM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time)+"43200";
} else {
$l_tstamp=strtotime($l_time);
}
$this->allMetrics[$l_tstamp]["cpu_user"]=$l_user;
$this->allMetrics[$l_tstamp]["cpu_nice"]=$l_nice;
$this->allMetrics[$l_tstamp]["cpu_system"]=$l_system;
$this->allMetrics[$l_tstamp]["cpu_iowait"]=$l_iowait;
}
if(ereg("CPU",$l_line))
{
$l_consider=true;
}
}
return true;
} else {
return false;
}
}
function getEthMetrics()
{
$l_cmd=$this->base_cmd." -n FULL";
$l_eth_metrics=$this->sshExec($l_cmd);
if($l_eth_metrics)
{
$l_consider=false;
foreach($l_eth_metrics as $l_line)
{
if(ereg("Average",$l_line))
{
break;
}
if($l_consider && ereg("eth0",$l_line))
{
list($l_time,$l_time_ampm,,,,$l_rxbyt,$l_txbyt)=sscanf($l_line,"%s %s %s %f %f %f %f");
if ($l_time_ampm=="AM" && preg_match("/^12:/",$l_time))
{
$l_tstamp=strtotime($l_time)-"43200";
} elseif($l_time_ampm=="AM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time);
} elseif($l_time_ampm=="PM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time)+"43200";
} else {
$l_tstamp=strtotime($l_time);
}
$this->allMetrics[$l_tstamp]["net_received"]=$l_rxbyt;
$this->allMetrics[$l_tstamp]["net_transmitted"]=$l_txbyt;
}
if(ereg("IFACE",$l_line))
{
$l_consider=true;
}
}
return true;
} else {
return false;
}
}
function getMemMetrics()
{
$l_cmd=$this->base_cmd." -r";
$l_mem_metrics=$this->sshExec($l_cmd);
if($l_mem_metrics)
{
$l_consider=false;
foreach($l_mem_metrics as $l_line)
{
if(ereg("Average",$l_line))
{
break;
}
if($l_consider)
{
list($l_time,$l_time_ampm,,,$l_memused,,,,,$l_swpused)=sscanf($l_line,"%s %s %d %d %f %d %d %d %d %f");
if ($l_time_ampm=="AM" && preg_match("/^12:/",$l_time))
{
$l_tstamp=strtotime($l_time)-"43200";
} elseif($l_time_ampm=="AM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time);
} elseif($l_time_ampm=="PM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time)+"43200";
} else {
$l_tstamp=strtotime($l_time);
}
$this->allMetrics[$l_tstamp]["memory_used"]=$l_memused;
$this->allMetrics[$l_tstamp]["swap_used"]=$l_swpused;
}
if(ereg("kbmemfree",$l_line))
{
$l_consider=true;
}
}
return true;
} else {
return false;
}
}
function getProcMetrics()
{
$l_cmd=$this->base_cmd." -q";
$l_proc_metrics=$this->sshExec($l_cmd);
if($l_proc_metrics)
{
$l_consider=false;
foreach($l_proc_metrics as $l_line)
{
if(ereg("Average",$l_line))
{
break;
}
if($l_consider)
{
list($l_time,$l_time_ampm,$l_proc_wait,$l_total_procs,$l_lavg_1,$l_lavg_5,$l_lavg_15)=sscanf($l_line,"%s %s %d %d %f %f %f");
if ($l_time_ampm=="AM" && preg_match("/^12:/",$l_time))
{
$l_tstamp=strtotime($l_time)-"43200";
} elseif($l_time_ampm=="AM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time);
} elseif($l_time_ampm=="PM" && !preg_match("/^12:/",$l_time)) {
$l_tstamp=strtotime($l_time)+"43200";
} else {
$l_tstamp=strtotime($l_time);
}
$this->allMetrics[$l_tstamp]["process_waiting"]=$l_proc_wait;
$this->allMetrics[$l_tstamp]["total_processes"]=$l_total_procs;
$this->allMetrics[$l_tstamp]["loadavg_1"]=$l_lavg_1;
$this->allMetrics[$l_tstamp]["loadavg_5"]=$l_lavg_5;
$this->allMetrics[$l_tstamp]["loadavg_15"]=$l_lavg_15;
}
if(ereg("runq-sz",$l_line))
{
$l_consider=true;
}
}
return true;
} else {
return false;
}
}
function createRRD()
{
$l_datadir=$this->cwd."/data/";
if(!is_dir($l_datadir))
{
mkdir($l_datadir);
}
$l_hostdatadir=$this->cwd."/data/".$this->host."/";
if(!is_dir($l_hostdatadir))
{
mkdir($l_hostdatadir);
}
foreach($this->allMetrics as $l_k => $l_v)
{
foreach($l_v as $l_metric => $l_value)
{
$l_cmd=$this->configs["path_to_rrdtool"]." create $l_hostdatadir".$l_metric.".rrd";
$l_cmd.=" --step 600 ";
$l_cmd.=" --start $l_k";
$l_cmd.=" DS:$l_metric:GAUGE:1200:U:U";
$l_cmd.=" RRA:AVERAGE:0.10:1:144";
exec($l_cmd);
}
break;
}
}
function updateRRD()
{
$l_hostdatadir=$this->cwd."/data/".$this->host."/";
if(is_dir($l_hostdatadir))
{
foreach($this->allMetrics as $l_k => $l_v)
{
foreach($l_v as $l_metric => $l_value)
{
$l_cmd=$this->configs["path_to_rrdtool"]." update $l_hostdatadir".$l_metric.".rrd";
$l_cmd.=" $l_k:$l_value";
exec($l_cmd);
}
}
}
}
function graphRRD()
{
$l_hostdatadir=$this->cwd."/data/".$this->host."/";
if(is_dir($l_hostdatadir))
{
$l_graphdir=$this->cwd."/graph/";
if(!is_dir($l_graphdir))
{
mkdir($l_graphdir);
}
$l_hostgraphdir=$this->cwd."/graph/".$this->host."/";
if(!is_dir($l_hostgraphdir))
{
mkdir($l_hostgraphdir);
}
$l_max=max(array_keys($this->allMetrics));
foreach($this->allMetrics as $l_k => $l_v)
{
foreach($l_v as $l_metric => $l_value)
{
$l_cmd=$this->configs["path_to_rrdtool"]." graph $l_hostgraphdir".$l_metric.".gif";
$l_cmd.=" --title=\"".$this->host." statistics generated from SAR : $l_metric\"";
$l_cmd.=" --end $l_max";
$l_cmd.=" --start $l_k";
$l_cmd.=" --width 400";
$l_cmd.=" DEF:$l_metric=$l_hostdatadir$l_metric.rrd";
$l_cmd.=":$l_metric:AVERAGE AREA:$l_metric#33BB22:\"";
$l_cmd.=$this->units[$l_metric]." $l_metric\"";
exec($l_cmd);
}
break;
}
}
}
function poll($selected_host,$day)
{
$this->host=$selected_host;
$this->hostarr=$this->hosts["$selected_host"];
$l_sarfile=$this->hostarr["sar_file_path"]."/".$this->configs["sarfile_prefix"].$day;
$l_sarexists=$this->sarFileExists($l_sarfile);
if($l_sarexists)
{
$this->base_cmd=$this->configs["sar_base_cmd"].$l_sarfile;
$l_cpu=$this->getCPUMetrics();
$l_eth=$this->getEthMetrics();
$l_mem=$this->getMemMetrics();
$l_proc=$this->getProcMetrics();
}
if($l_cpu && $l_eth && $l_mem && $l_proc)
{
$this->createRRD();
$this->updateRRD();
$this->graphRRD();
return true;
} else {
return false;
}
}
}
?>