mirror of
https://codeberg.org/mclemens/tsmmonitor2.git
synced 2024-12-22 07:06:48 -05:00
- First try of a multi-process poller implementation. Probably still
buggy and needs alterations to the DB backend.
This commit is contained in:
parent
e82d671bdd
commit
8809708d3d
@ -101,6 +101,13 @@ if ($version != $config["tsm_monitor_version"] && basename($_SERVER['REQUEST_URI
|
||||
exit;
|
||||
}
|
||||
|
||||
$polld_maxproc = $adodb->fetchCellDB("SELECT confval FROM cfg_config WHERE confkey='polld_maxproc'", '');
|
||||
if (isset($polld_maxproc)) {
|
||||
$config["polld_maxproc"] = $polld_maxproc;
|
||||
} else {
|
||||
$config["polld_maxproc"] = 5;
|
||||
}
|
||||
|
||||
// ** Include generic code and external libraries ** //
|
||||
// ... more includes here
|
||||
|
||||
|
@ -23,11 +23,11 @@
|
||||
/**
|
||||
*
|
||||
* polld.php, TSM Monitor
|
||||
*
|
||||
*
|
||||
* This file is the TSM Monitor Polling Daemon. It executes queries against TSM
|
||||
* and inserts them into TMS Monitor's MySQL Database
|
||||
*
|
||||
* @author Michael Clemens
|
||||
* and inserts them into TSM Monitor's MySQL Database
|
||||
*
|
||||
* @author Michael Clemens, Frank Fegert
|
||||
* @version 1.0
|
||||
* @package tsmmonitor
|
||||
*/
|
||||
@ -60,9 +60,9 @@ class PollD {
|
||||
|
||||
|
||||
/**
|
||||
* PollD
|
||||
*
|
||||
* @param mixed $adodb
|
||||
* PollD
|
||||
*
|
||||
* @param mixed $adodb
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@ -94,7 +94,7 @@ class PollD {
|
||||
$this->writeMSG("TSM Monitor has not been installed correctly, path to dsmadmc could not be found.\n", "ERROR");
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$this->servers = $this->getServers();
|
||||
$this->queries = $this->getQueries();
|
||||
$this->overviewqueries = $this->getOverviewQueries();
|
||||
@ -102,9 +102,9 @@ class PollD {
|
||||
|
||||
|
||||
/**
|
||||
* writeMSG
|
||||
*
|
||||
* @param mixed $msg
|
||||
* writeMSG
|
||||
*
|
||||
* @param mixed $msg
|
||||
* @param mixed $level VERBOSE, INFO, WARN, ERROR, OFF
|
||||
* @access public
|
||||
* @return void
|
||||
@ -141,8 +141,8 @@ class PollD {
|
||||
|
||||
|
||||
/**
|
||||
* setDebuglevel
|
||||
*
|
||||
* setDebuglevel
|
||||
*
|
||||
* @param mixed $debuglevel VERBOSE, INFO, WARN, ERROR, OFF
|
||||
* @access public
|
||||
* @return void
|
||||
@ -172,6 +172,7 @@ class PollD {
|
||||
/**
|
||||
* getQueries - returns an array filled with all configured TSM queries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getQueries() {
|
||||
$queries = array();
|
||||
@ -230,7 +231,7 @@ class PollD {
|
||||
* @param string $query TSM query
|
||||
* @param string $servername name of the TSM server
|
||||
* @param string $restable
|
||||
* @param string $timestamp
|
||||
* @param string $timestamp
|
||||
* @param string $overviewname
|
||||
* @return array
|
||||
*/
|
||||
@ -441,7 +442,7 @@ class PollD {
|
||||
}
|
||||
} else {
|
||||
$this->writeMSG("There was a problem querying the TSM Server ".$server["servername"]."!\n", "ERROR");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->writeMSG("no need to update result -> pollfreq not reached!\n", "INFO");
|
||||
$this->log_pollfreqnoreached++;
|
||||
@ -482,7 +483,7 @@ class PollD {
|
||||
/**
|
||||
* cleanupDatabase - cleans up database (single result tables and/or hash entry)
|
||||
*
|
||||
* @param string $servername
|
||||
* @param string $servername
|
||||
* @param string $queryname
|
||||
* @param string $overviewqueryname
|
||||
* @param string $hashonly do not drop table, just delete entry in log_hashes
|
||||
@ -492,7 +493,7 @@ class PollD {
|
||||
if ($servername != "" && $queryname != "" && $overviewqueryname != "") {
|
||||
$time = time()-($months*30*24*60*60);
|
||||
$wc = " WHERE `timestamp`<'".$time."'";
|
||||
foreach ($this->servers as $server) {
|
||||
foreach ($this->servers as $server) {
|
||||
if ($servername == "all" || $server["servername"] == $servername) {
|
||||
foreach ($this->queries as $query) {
|
||||
if (($queryname == "all" || $query["name"] == $queryname) && $queryname != "none") {
|
||||
@ -620,21 +621,21 @@ class PollD {
|
||||
foreach ($this->overviewqueries as $query) {
|
||||
$this->pollOverviewQuery($query, $server, $timestamp);
|
||||
}
|
||||
$sql = 'INSERT INTO log_polldlog VALUES ("'.$timestamp.'", "'.$server["servername"].'", "'.$log_updated.'", "'.$log_unchangedresult.'", "'.$log_pollfreqnoreached.'", "'.(time()-$log_timeneeded).'")';
|
||||
$sql = 'INSERT INTO log_polldlog VALUES ("'.$timestamp.'", "'.$server["servername"].'", "'.$this->log_updated.'", "'.$this->log_unchangedresult.'", "'.$this->log_pollfreqnoreached.'", "'.(time() - $this->log_timeneeded).'")';
|
||||
$this->adodb->execDB($sql);
|
||||
}
|
||||
$init = "no";
|
||||
|
||||
|
||||
$this->writeMSG("needed ".(time()-$timestamp)." seconds for this run.\n", "INFO");
|
||||
$tempsleeptime = 900 -(time()-$timestamp);
|
||||
$this->writeMSG("needed ".(time() - $timestamp)." seconds for this run.\n", "INFO");
|
||||
$tempsleeptime = 900 - (time() - $timestamp);
|
||||
if ($tempsleeptime < 0) {
|
||||
$tempsleeptime = 0;
|
||||
}
|
||||
$this->writeMSG("sleeping for ".$tempsleeptime." seconds...\n", "WARN");
|
||||
$this->writeMSG("next run will be at ".strftime("%H:%M:%S", (time()+$tempsleeptime))."\n\n", "WARN");
|
||||
$this->writeMSG("next run will be at ".strftime("%H:%M:%S", (time() + $tempsleeptime))."\n\n", "WARN");
|
||||
|
||||
$this->setPollDStatus("sleeping", $timestamp, (time()+$tempsleeptime));
|
||||
$this->setPollDStatus("sleeping", $timestamp, (time() + $tempsleeptime));
|
||||
|
||||
sleep ($tempsleeptime);
|
||||
|
||||
@ -648,4 +649,691 @@ class PollD {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Class PollD_MP
|
||||
*
|
||||
*/
|
||||
class PollD_MP {
|
||||
|
||||
var $cfg;
|
||||
var $queries;
|
||||
var $lastrun;
|
||||
var $overviewqueries;
|
||||
var $adodb;
|
||||
var $dsmadmc;
|
||||
|
||||
var $debuglevel; // VERBOSE=4, INFO=3, WARN=2, ERROR=1, OFF=0
|
||||
var $logfile;
|
||||
|
||||
var $log_timeneeded;
|
||||
var $log_unchangedresult;
|
||||
var $log_pollfreqnoreached;
|
||||
var $log_updated;
|
||||
var $pid;
|
||||
var $child_pid;
|
||||
var $worker_pids = array();
|
||||
|
||||
/**
|
||||
* PollD_MP
|
||||
*
|
||||
* @param mixed $cfg
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function PollD_MP($cfg) {
|
||||
|
||||
$this->cfg = $cfg;
|
||||
$funcs = array("pcntl_fork", "pcntl_waitpid", "posix_kill");
|
||||
$func_miss = array();
|
||||
$func_ena = true;
|
||||
|
||||
// pcntl_fork() not available on win32, sorry folks!
|
||||
if ($cfg["server_os"] == "win32") {
|
||||
echo "ERROR: The PHP function \"pcntl_fork()\" is not available on Windows platforms, please use the regular tmonpolld.php!\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check if PHP has pcntl_fork() enabled.
|
||||
foreach ($funcs as $func) {
|
||||
if (!function_exists($func)){
|
||||
$func_ena = false;
|
||||
array_push($func_miss, $func);
|
||||
}
|
||||
}
|
||||
if (!$func_ena) {
|
||||
echo "ERROR: The following PHP functions are missing: ".(implode(", ", $func_miss)).".\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->setDebuglevel("INFO");
|
||||
$this->adodb = new ADOdb($this->cfg["db_host"], $this->cfg["db_port"], $this->cfg["db_user"], $this->cfg["db_password"], $this->cfg["db_name"], $this->cfg["db_type"]);
|
||||
$sql = "select confval from cfg_config WHERE `confkey`='loglevel_polld'";
|
||||
$loglevel = $this->adodb->fetchArrayDB($sql);
|
||||
$loglevel = strtoupper($loglevel[0]["confval"]);
|
||||
$this->setDebuglevel("$loglevel");
|
||||
$sql = "select confval from cfg_config WHERE `confkey`='path_polldlog'";
|
||||
$lf = $this->adodb->fetchArrayDB($sql);
|
||||
if ($lf[0]["confval"] != "") {
|
||||
$this->logfile = $lf[0]["confval"];
|
||||
} else {
|
||||
unset($this->logfile);
|
||||
}
|
||||
$sql = "select confval from cfg_config WHERE `confkey`='path_dsmadmc'";
|
||||
$tsmclient = $this->adodb->fetchArrayDB($sql);
|
||||
if ($tsmclient[0]["confval"] != "") {
|
||||
$this->dsmadmc = $tsmclient[0]["confval"];
|
||||
if (!is_executable($this->dsmadmc)) {
|
||||
$this->writeMSG("$this->dsmadmc is not executable.\n", "ERROR");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$this->writeMSG("TSM Monitor has not been installed correctly, path to dsmadmc could not be found.\n", "ERROR");
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->servers = $this->getServers();
|
||||
$this->queries = $this->getQueries();
|
||||
$this->overviewqueries = $this->getOverviewQueries();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* writeMSG
|
||||
*
|
||||
* @param mixed $msg
|
||||
* @param mixed $level VERBOSE, INFO, WARN, ERROR, OFF
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function writeMSG($msg, $level) {
|
||||
|
||||
switch ($level) {
|
||||
case ("OFF"):
|
||||
$ilevel = 0;
|
||||
break;
|
||||
case ("ERROR"):
|
||||
$ilevel = 1;
|
||||
break;
|
||||
case ("WARN"):
|
||||
$ilevel = 2;
|
||||
break;
|
||||
case ("INFO"):
|
||||
$ilevel = 3;
|
||||
break;
|
||||
case ("VERBOSE"):
|
||||
$ilevel = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->debuglevel >= $ilevel) {
|
||||
if ($loghandle = fopen($this->logfile, 'a')) {
|
||||
$starttime = microtime();
|
||||
do {
|
||||
$lock = flock($loghandle, LOCK_EX);
|
||||
if (!$lock) usleep(round(rand(0, 100) * 1000));
|
||||
} while (!$lock && ((microtime() - $starttime) < 1000));
|
||||
|
||||
if ($lock) {
|
||||
fwrite($loghandle, $level.": ".$msg);
|
||||
}
|
||||
fclose($loghandle);
|
||||
} else {
|
||||
echo "ERROR: Cannot open logfile: '".$logfile."' for writing. Falling back to STDOUT.\n";
|
||||
echo $level.": ".$msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* setDebuglevel
|
||||
*
|
||||
* @param mixed $debuglevel VERBOSE, INFO, WARN, ERROR, OFF
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setDebuglevel($debuglevel) {
|
||||
|
||||
switch ($debuglevel) {
|
||||
case ("OFF"):
|
||||
$this->debuglevel = 0;
|
||||
break;
|
||||
case ("ERROR"):
|
||||
$this->debuglevel = 1;
|
||||
break;
|
||||
case ("WARN"):
|
||||
$this->debuglevel = 2;
|
||||
break;
|
||||
case ("INFO"):
|
||||
$this->debuglevel = 3;
|
||||
break;
|
||||
case ("VERBOSE"):
|
||||
$this->debuglevel = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getQueries - returns an array filled with all configured TSM queries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getQueries() {
|
||||
$queries = array();
|
||||
$query = "select * from cfg_queries";
|
||||
$querytablerows = $this->adodb->fetchArrayDB($query);
|
||||
while (list ($subkey, $queryrow) = each ($querytablerows)) {
|
||||
$queries[$queryrow["name"]] = (array)$queryrow;
|
||||
$temparray=split(",", $queryrow->Fields);
|
||||
$cols = array();
|
||||
while (list ($subkey, $col) = each ($temparray)) {
|
||||
$temp = split("!", $col);
|
||||
$cols[$subkey]["label"] = $temp[0];
|
||||
$cols[$subkey]["name"] = $temp[1];
|
||||
}
|
||||
if ($queryrow->name != "") $queries[$queryrow->name]["header"]["column"] = $cols;
|
||||
}
|
||||
return $queries;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getOverviewQueries - returns an array filled with all configured TSM overview queries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getOverviewQueries() {
|
||||
$queries = array();
|
||||
$query = "select * from cfg_overviewqueries";
|
||||
$querytablerows = $this->adodb->fetchArrayDB($query);
|
||||
while (list ($subkey, $queryrow) = each ($querytablerows)) {
|
||||
$queries[$queryrow["name"]] = (array)$queryrow;
|
||||
}
|
||||
return $queries;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getServers - returns an array containing all defined servers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getServers() {
|
||||
$query = "SELECT * FROM cfg_servers";
|
||||
$rows = $this->adodb->fetchArrayDB($query);
|
||||
$servers = array();
|
||||
while (list ($key, $val) = each ($rows)) {
|
||||
$servers[$val["servername"]] = (array)$val;
|
||||
}
|
||||
return $servers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* updateJoblist - update the job list for the worker processes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function updateJoblist() {
|
||||
$servers = $this->getServers();
|
||||
$query = "SELECT * FROM job_list";
|
||||
$jobs = $this->adodb->fetchArrayDB($query);
|
||||
$insert = array();
|
||||
|
||||
foreach ($servers as $skey => $sval) {
|
||||
$found = 0;
|
||||
$sservername = strtoupper($sval["servername"]);
|
||||
foreach ($jobs as $jkey => $jval) {
|
||||
$jservername = strtoupper($jval["servername"]);
|
||||
if (isset($sservername) && isset($jservername)) {
|
||||
if ($sservername == $jservername) {
|
||||
$found = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($found == 0) array_push($insert, "('".$sservername."')");
|
||||
}
|
||||
|
||||
if (count($insert) > 0) {
|
||||
$sql = "INSERT INTO `job_list` (`servername`) VALUES ".join(', ', $insert);
|
||||
$this->adodb->execDB($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* execute - executes a TSM query on a TSM server and returns an array containing SQL insert statements including the results
|
||||
*
|
||||
* @param string $query TSM query
|
||||
* @param string $servername name of the TSM server
|
||||
* @param string $restable
|
||||
* @param string $timestamp
|
||||
* @param string $overviewname
|
||||
* @return array
|
||||
*/
|
||||
function execute($query = '', $servername = '', $restable = '', $timestamp = '', $overviewname = '') {
|
||||
|
||||
$server = $this->servers[$servername];
|
||||
$ip = $server["ip"];
|
||||
$port = $server["port"];
|
||||
$user = $server["username"];
|
||||
$pass = $server["password"];
|
||||
$out = array();
|
||||
|
||||
$originalquery = $query;
|
||||
$query = ereg_replace("NOTEQUAL","<>",$query);
|
||||
$query = ereg_replace("LESS","<",$query);
|
||||
|
||||
if (ereg(" summary ", $query)) {
|
||||
if ($this->lastrun > 0) {
|
||||
$tdiff = $timestamp - $this->lastrun;
|
||||
$tdiff = ceil($tdiff / 60) * 60;
|
||||
$query = ereg_replace(" @@@WHERE@@@ "," AND start_time>current_timestamp-($tdiff)seconds ",$query);
|
||||
} else {
|
||||
$query = ereg_replace(" @@@WHERE@@@ "," ",$query);
|
||||
}
|
||||
}
|
||||
|
||||
$popen_flags = ($this->cfg["server_os"] == "win32") ? 'rb' : 'r';
|
||||
$handle = popen("$this->dsmadmc -se=$servername -id=$user -password=$pass -TCPServeraddress=$ip -COMMMethod=TCPIP -TCPPort=$port -dataonly=yes -TAB \"$query\" ", "$popen_flags");
|
||||
|
||||
$hashstring = "";
|
||||
|
||||
if ($handle) {
|
||||
while (!feof($handle) && !$stop) {
|
||||
$read = fgets($handle, 4096);
|
||||
$hashstring .= $read;
|
||||
$stop = strstr($read, 'ANR2034E');
|
||||
$stop = strstr($read, 'ANS1017E');
|
||||
$stop = strstr($read, 'ANS8023E');
|
||||
$blank = strstr($read, 'ANR2034E'); // dsmadmc runs correctly but result is empty (e.g. processes)
|
||||
if ($read != ' ' && $read != '' && !$stop) {
|
||||
if ($blank == "") {
|
||||
$read = preg_replace('/[\n]+/', '', $read);
|
||||
$read = ereg_replace("\t","\",\"",$read);
|
||||
$read = ereg_replace("\\\\",'\\\\',$read);
|
||||
if ($overviewname == '') {
|
||||
$out[] = 'INSERT IGNORE INTO '.$restable.' values ("'.$timestamp.'", "'.$read.'")';
|
||||
} else {
|
||||
$out[] = 'INSERT INTO '.$restable.' (timestamp, name, result) values ("'.$timestamp.'", "'.$overviewname.'", "'.$read.'") ON DUPLICATE KEY update result="'.$read.'", timestamp="'.$timestamp.'"';
|
||||
}
|
||||
} else { // result is empty and it's ok
|
||||
$out[0] = 'INSERT IGNORE INTO '.$restable.' (timestamp) values ("'.$timestamp.'")';
|
||||
$hashstring = "";
|
||||
$stop = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return["sql"] = $out;
|
||||
$return["md5"] = md5($hashstring);
|
||||
if (!$stop || ($blank && $stop)) {
|
||||
return $return;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* checkHash - checks with checksum if there's already the same result in the result database. If not, the hash will be stored.
|
||||
*
|
||||
* @param string $tablename name of table
|
||||
* @param string $hash md5 hash checksum of current resultSet
|
||||
* @return boolean
|
||||
*/
|
||||
function checkHash($tablename = '', $hash = '') {
|
||||
|
||||
$sql = "select count(*) from log_hashes where TABLENAME='".$tablename."' and HASH='".$hash."'";
|
||||
$countobj = $this->adodb->fetchArrayDB($sql);
|
||||
$countarray = (array)$countobj[0];
|
||||
$count = $countarray["count(*)"];
|
||||
|
||||
if ($count > 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
$colarray = array();
|
||||
$colarray["tablename"] = $tablename;
|
||||
$colarray["hash"] = $hash;
|
||||
$this->adodb->updateDB("log_hashes", $colarray, 'tablename');
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* checkFreq - checks if configured checking frequency is reached
|
||||
*
|
||||
* @param string $tablename name of table
|
||||
* @param string $pollfreq polling frequency
|
||||
* @param string $timestamp timestamp
|
||||
* @return boolean
|
||||
*/
|
||||
function checkFreq($tablename, $pollfreq, $timestamp) {
|
||||
|
||||
$sql = "select MAX(TimeStamp) from ".$tablename;
|
||||
$res = $this->adodb->fetchArrayDB($sql);
|
||||
$resarray = $res[0];
|
||||
$lastinsert = $resarray["MAX(TimeStamp)"];
|
||||
|
||||
if ($lastinsert != "") {
|
||||
$this->lastrun = $lastinsert;
|
||||
} else {
|
||||
$this->lastrun = 0;
|
||||
}
|
||||
|
||||
if ($lastinsert != "" && ($lastinsert+($pollfreq*60)) >= $timestamp) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getSleeptime - searches for the smallest polling frequency and returns the time to sleep
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getSleeptime() {
|
||||
|
||||
$sql = "select MIN(pollfreq) from cfg_queries";
|
||||
$res = $this->adodb->fetchArrayDB($sql);
|
||||
$resarray = (array)$res[0];
|
||||
$minqueries = $resarray["MIN(pollfreq)"];
|
||||
|
||||
$sql = "select MIN(pollfreq) from cfg_overviewqueries";
|
||||
$res = $this->adodb->fetchArrayDB($sql);
|
||||
$resarray = (array)$res[0];
|
||||
$minoverview = $resarray["MIN(pollfreq)"];
|
||||
|
||||
return min($minoverview,$minqueries)*60;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pollQuery - executes a TSM query and stores result in MySQL DB
|
||||
*
|
||||
* @param array $query
|
||||
* @param array $server
|
||||
* @param boolean $ignorePollFreq
|
||||
* @param string $timestamp
|
||||
*/
|
||||
function pollQuery($query = "", $server = "", $ignorePollFreq = TRUE, $timestamp) {
|
||||
$starttquery = time();
|
||||
$querytime = 0;
|
||||
|
||||
$logprefix = "Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." ---------".$query["name"];
|
||||
$tablename = "res_".$query["name"]."_".$server;
|
||||
|
||||
// create table if not exists
|
||||
$showsql = "SHOW TABLES LIKE '".$tablename."'";
|
||||
$res = $this->adodb->fetchArrayDB($showsql);
|
||||
if (!isset($res[0])) {
|
||||
$fieldsql = "select fields from cfg_queries where name='".$query["name"]."'";
|
||||
$fields = $this->adodb->fetchArrayDB($fieldsql);
|
||||
$ctsql = "CREATE TABLE `".$tablename."` (".$fields[0]['fields'].") DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
|
||||
if (!$ignorePollFreq) {
|
||||
$this->writeMSG($logprefix.": created table ".$tablename."\n", "INFO");
|
||||
}
|
||||
$this->adodb->execDB($ctsql);
|
||||
}
|
||||
// execute query and store result in mysql db
|
||||
if ($ignorePollFreq || !$this->checkFreq($tablename, $query["pollfreq"], $timestamp)) {
|
||||
try {
|
||||
$result = $this->execute($query["tsmquery"], $server, $tablename, $timestamp);
|
||||
} catch (exception $e) {
|
||||
$this->writeMSG($logprefix.": Problem while querying from TSM Server!\n", "ERROR");
|
||||
}
|
||||
if ($result != "") {
|
||||
if (!$this->checkHash($tablename, $result["md5"])) {
|
||||
if ($query["polltype"] == "update") {
|
||||
$dropsql = "truncate table ".$tablename;
|
||||
try {
|
||||
$this->adodb->execDB($dropsql);
|
||||
} catch (exception $e) {
|
||||
$this->writeMSG($logprefix.": Error while truncating table (".$dropsql.")\n", "ERROR");
|
||||
}
|
||||
$this->writeMSG($logprefix.": TRUNCATED TABLE\n", "INFO");
|
||||
}
|
||||
foreach ($result["sql"] as $insertquery) {
|
||||
try {
|
||||
$this->adodb->execDB($insertquery);
|
||||
} catch (exception $e) {
|
||||
$this->writeMSG($logprefix.": Error while inserting into table (".$insertquery.")\n", "ERROR");
|
||||
}
|
||||
}
|
||||
$querytime = time() - $starttquery;
|
||||
$this->writeMSG($logprefix.": Inserted new rows into ".$tablename." ($querytime sec)\n", "INFO");
|
||||
$this->log_updated++;
|
||||
} else {
|
||||
$querytime = time() - $starttquery;
|
||||
$this->writeMSG($logprefix.": No need to update result -> result is the same as last time ($querytime sec)\n", "INFO");
|
||||
$this->log_unchangedresult++;
|
||||
}
|
||||
} else {
|
||||
$this->writeMSG($logprefix.": There was a problem querying the TSM Server ".$server."!\n", "ERROR");
|
||||
}
|
||||
} else {
|
||||
$this->writeMSG($logprefix.": No need to update result -> pollfreq not reached!\n", "INFO");
|
||||
$this->log_pollfreqnoreached++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pollOverviewQuery - executes a TSM overview query and stores result in MySQL DB
|
||||
*
|
||||
* @param array $query
|
||||
* @param array $server
|
||||
* @param boolean $ignorePollFreq
|
||||
* @param string $timestamp
|
||||
*/
|
||||
function pollOverviewQuery($query = "", $server = "", $timestamp) {
|
||||
|
||||
$starttquery = time();
|
||||
$querytime = 0;
|
||||
|
||||
$tablename = "res_overview_".$server;
|
||||
$logprefix = "Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." ---------".$query["name"];
|
||||
$ctsql = "CREATE TABLE IF NOT EXISTS ".$tablename." ( `timestamp` int(11) collate utf8_unicode_ci NOT NULL, `name` varchar(35) collate utf8_unicode_ci NOT NULL, `result` varchar(255) collate utf8_unicode_ci NOT NULL, UNIQUE KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
|
||||
$this->adodb->execDB($ctsql);
|
||||
$result = $this->execute($query["query"], $server, $tablename, $timestamp, $query["name"]);
|
||||
if ($result != "") {
|
||||
foreach ($result["sql"] as $insertquery) {
|
||||
$this->adodb->execDB($insertquery);
|
||||
$querytime = time() - $starttquery;
|
||||
$this->writeMSG($logprefix.": Inserted row ($querytime sec)\n", "INFO");
|
||||
}
|
||||
} else {
|
||||
$this->writeMSG($logprefix.": There was a problem querying the TSM Server ".$server."!\n", "ERROR");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* setPollDStatus
|
||||
*
|
||||
* @param string $server
|
||||
* @param string $status
|
||||
* @param string $pid
|
||||
* @param string $lastrun
|
||||
* @param string $nextrun
|
||||
*/
|
||||
function setPollDStatus($server, $status, $pid, $lastrun, $nextrun) {
|
||||
|
||||
if ($server != "") $servername = $server;
|
||||
$sqlset = array();
|
||||
array_push($sqlset, "`status`='".$status."'");
|
||||
array_push($sqlset, "`pid`='".$pid."'");
|
||||
array_push($sqlset, "`lastrun`='".$lastrun."'");
|
||||
array_push($sqlset, "`nextrun`='".$nextrun."'");
|
||||
|
||||
$sql = "UPDATE job_list SET ".(join(', ', $sqlset))." WHERE servername='".$server."'";
|
||||
$this->adodb->execDB($sql);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* isEnabled - returns true if PollD is enabled
|
||||
*
|
||||
* @returns boolean
|
||||
*/
|
||||
function isEnabled() {
|
||||
|
||||
$sql = "select enabled from log_polldstat WHERE `id`='1'";
|
||||
$result = $this->adodb->fetchArrayDB($sql);
|
||||
|
||||
if ($result != "" && $result[0]["enabled"] == "1") {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* controlPollD - enables or disables polld
|
||||
*
|
||||
* @param string switch on or off
|
||||
*/
|
||||
function controlPollD($switch = "") {
|
||||
|
||||
if ($switch == "on") {
|
||||
$val = "1";
|
||||
} else if ($switch == "off") {
|
||||
$val = "0";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
$sql = "update log_polldstat set `enabled` = '".$val."' WHERE `id`='1'";
|
||||
$this->adodb->execDB($sql);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* poll - the main function that polls the data
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function poll() {
|
||||
|
||||
$sleeptime = $this->getSleeptime();
|
||||
$this->writeMSG("Sleeptime will be ".$sleeptime." seconds\n", "WARN");
|
||||
|
||||
if ($this->isEnabled()) {
|
||||
// Main loop for dispatcher
|
||||
while(true) {
|
||||
$this->adodb = new ADOdb($this->cfg["db_host"], $this->cfg["db_port"], $this->cfg["db_user"], $this->cfg["db_password"], $this->cfg["db_name"], $this->cfg["db_type"]);
|
||||
$this->updateJoblist($this->adodb);
|
||||
$query = "SELECT * FROM job_list";
|
||||
$jobs = $this->adodb->fetchArrayDB($query);
|
||||
$this->adodb->closeDB();
|
||||
|
||||
foreach ($jobs as $key => $job) {
|
||||
$this->lastrun = $job["lastrun"];
|
||||
$lastrun = $job["lastrun"];
|
||||
$lastpid = $job["pid"];
|
||||
$nextrun = $job["nextrun"];
|
||||
$server = $job["servername"];
|
||||
$status = $job["status"];
|
||||
if ($lastrun == "NULL" || $lastrun == "") $lastrun = 0;
|
||||
if ($nextrun == "NULL" || $nextrun == "") $nextrun = 0;
|
||||
$thisrun = time();
|
||||
|
||||
// Check for unclean child shutdown or hung child.
|
||||
if ($status == "running" ) {
|
||||
if ((posix_kill($lastpid, 0)) && (($thisrun - $lastrun) > 3600)) {
|
||||
$this->writeMSG("Killing child: $lastpid for server: $server after 3600 sec.\n", INFO);
|
||||
posix_kill($lastpid, SIGTERM);
|
||||
unset($this->worker_pids[$lastpid]);
|
||||
$nextrun = 0;
|
||||
$status = "";
|
||||
} else if (!posix_kill($lastpid, 0)) {
|
||||
$this->writeMSG("Removing non-existing child: $lastpid for server: $server from job list.\n", INFO);
|
||||
unset($this->worker_pids[$lastpid]);
|
||||
$nextrun = 0;
|
||||
$status = "";
|
||||
}
|
||||
}
|
||||
|
||||
if ($status == "" && $thisrun >= $nextrun) {
|
||||
if (count($this->worker_pids) < $this->cfg["polld_maxproc"]) {
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($pid == -1) {
|
||||
echo "ERROR: Couldn't fork() worker process!";
|
||||
exit;
|
||||
} else if ($pid) {
|
||||
// Parent
|
||||
$this->worker_pids[$pid] = 1;
|
||||
$this->writeMSG("Dispatcher: ".(posix_getpid())."; Workers: ".(join(', ', array_keys($this->worker_pids)))."\n", INFO);
|
||||
|
||||
} else {
|
||||
// Child
|
||||
$this->child_pid = posix_getpid();
|
||||
$timestamp = time();
|
||||
$this->writeMSG("Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." Timestamp for this run is $timestamp.\n", INFO);
|
||||
$this->adodb = new ADOdb($this->cfg["db_host"], $this->cfg["db_port"], $this->cfg["db_user"], $this->cfg["db_password"], $this->cfg["db_name"], $this->cfg["db_type"]);
|
||||
$this->setPollDStatus($server, "running", $this->child_pid, $timestamp, "");
|
||||
|
||||
// Process job
|
||||
$this->log_timeneeded = $timestamp;
|
||||
$this->log_unchangedresult = 0;
|
||||
$this->log_pollfreqnoreached = 0;
|
||||
$this->log_updated = 0;
|
||||
|
||||
$this->writeMSG("Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." ---querying server $server\n", "WARN");
|
||||
$this->writeMSG("Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." ------querying normal queries\n", "WARN");
|
||||
foreach ($this->queries as $query) {
|
||||
$this->pollQuery($query, $server, FALSE, $timestamp);
|
||||
}
|
||||
$this->writeMSG("Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." ------querying overview queries\n", "WARN");
|
||||
foreach ($this->overviewqueries as $query) {
|
||||
$this->pollOverviewQuery($query, $server, $timestamp);
|
||||
}
|
||||
|
||||
$this->writeMSG("Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." Needed ".(time()-$timestamp)." seconds for this run.\n", "INFO");
|
||||
$tempsleeptime = 900 - (time() - $timestamp);
|
||||
if ($tempsleeptime < 0) $tempsleeptime = 0;
|
||||
$this->writeMSG("Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." Next run will be at ".strftime("%H:%M:%S", (time() + $tempsleeptime))."\n", "WARN");
|
||||
|
||||
$sql = 'INSERT INTO log_polldlog VALUES ("'.$timestamp.'", "'.$server.'", "'.$this->log_updated.'", "'.$this->log_unchangedresult.'", "'.$this->log_pollfreqnoreached.'", "'.(time() - $this->log_timeneeded).'")';
|
||||
$this->adodb->execDB($sql);
|
||||
|
||||
$this->setPollDStatus($server, "", "", $timestamp, (time() + $tempsleeptime));
|
||||
$this->adodb->closeDB();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->worker_pids as $wpid => $val) {
|
||||
$wpid_status = pcntl_waitpid($wpid, $status, WNOHANG);
|
||||
if ($wpid_status < 0) {
|
||||
echo "ERROR: pcntl_waitpid returned $wpid_status\n";
|
||||
exit;
|
||||
} else if ($wpid_status > 0) {
|
||||
$this->writeMSG("Worker($wpid_status) has exited.\n", INFO);
|
||||
unset($this->worker_pids[$wpid]);
|
||||
}
|
||||
}
|
||||
sleep(rand(5,10));
|
||||
}
|
||||
} else {
|
||||
$this->writeMSG("PollD is disabled. Sleeping for 5 minutes ...\n", "ERROR");
|
||||
sleep (3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
43
polld/tmonpolld_mp.php
Normal file
43
polld/tmonpolld_mp.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
************************************************************************
|
||||
This file is part of TSM Monitor.
|
||||
|
||||
TSM Monitor 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.
|
||||
|
||||
TSM Monitor 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 TSM Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||
************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* tmonpolld_mp.php, TSM Monitor
|
||||
*
|
||||
* This file instantiates PollD_MP and executes the multi-process polling.
|
||||
* Start it like this: 'nohup php tmonpolld_mp.php &'
|
||||
*
|
||||
*
|
||||
* @author Michael Clemens, Frank Fegert
|
||||
* @version 1.0
|
||||
* @package tsmmonitor
|
||||
*/
|
||||
|
||||
include_once("../includes/global.php");
|
||||
|
||||
$tmonpolld = new PollD_MP($config);
|
||||
$tmonpolld->controlPollD("on");
|
||||
$tmonpolld->poll();
|
||||
|
||||
|
||||
?>
|
@ -62,7 +62,8 @@ INSERT INTO `cfg_config` (`id`, `confkey`, `confval`, `description`) VALUES
|
||||
(5, 'loglevel_tm', 'INFO', 'TSM Monitor Log Level'),
|
||||
(6, 'loglevel_polld', 'INFO', 'PollD Log Level'),
|
||||
(7, 'path_dsmadmc', '', 'dsmadmc Binary Path'),
|
||||
(8, 'path_php', '', 'PHP Binary Path');
|
||||
(8, 'path_php', '', 'PHP Binary Path'),
|
||||
(9, 'polld_maxproc', '5', 'PollD maximum concurrent processes');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
@ -364,3 +365,21 @@ CREATE TABLE IF NOT EXISTS `log_polldstat` (
|
||||
|
||||
INSERT INTO `log_polldstat` (`id`, `enabled`, `status`, `lastrun`, `nextrun`) VALUES
|
||||
(1, 0, '', 0, 0);
|
||||
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `job_list`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `job_list` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`servername` varchar(35) collate utf8_unicode_ci NOT NULL,
|
||||
`status` varchar(35) collate utf8_unicode_ci NOT NULL,
|
||||
`pid` int(11) default NULL,
|
||||
`lastrun` int(11) default NULL,
|
||||
`nextrun` int(11) default NULL
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
|
||||
|
Loading…
Reference in New Issue
Block a user