- Added STDOUT logging for PollD_MP if no logfile is configured.

- Added new exception handling and logging for ADODB.
This commit is contained in:
Frank Fegert 2009-07-12 17:12:14 +00:00
parent 8882989945
commit 97afaa73a6
4 changed files with 269 additions and 207 deletions

View File

@ -1143,7 +1143,7 @@ function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null)
$s .= "\n"; $s .= "\n";
} }
if ($html) $s .= '</pre>'; if ($html) $s .= '</pre>';
if ($printOrArr) print $s; // if ($printOrArr) print $s;
return $s; return $s;
} }
@ -1190,4 +1190,4 @@ function _adodb_find_from($sql)
} }
*/ */
?> ?>

View File

@ -40,225 +40,280 @@
class ADOdb { class ADOdb {
var $conn; var $conn;
var $debug; var $debug;
var $logfile;
/** /**
* constructor - establishes a DB connection via ADODB * constructor - establishes a DB connection via ADODB
* *
* @param string $host the hostname of the DB server * @param string $host the hostname of the DB server
* @param string $port the portnumber for the DB connection * @param string $port the portnumber for the DB connection
* @param string $user the username for the DB connection * @param string $user the username for the DB connection
* @param string $pass the password for the DB connection * @param string $pass the password for the DB connection
* @param string $db_name the name of the DB * @param string $db_name the name of the DB
* @param string $db_type the type of the DB (currently only 'mysql') * @param string $db_type the type of the DB (currently only 'mysql')
* @param string $retr the number attempts for the DB connection before a failure is reported * @param string $retr the number attempts for the DB connection before a failure is reported
* @return 0 * @return 0
*/ */
function ADOdb($host, $port = "3306", $user, $pass, $db_name, $db_type, $retr = 20, $debug = FALSE) { function ADOdb($host, $port = "3306", $user, $pass, $db_name, $db_type, $retr = 20, $debug = FALSE, $logfile = FALSE) {
$this->debug = $debug; $this->debug = $debug;
if ($logfile != FALSE) $this->logfile = $logfile;
$try = 0; $try = 0;
$hostport = $host . ":" . $port; $hostport = $host . ":" . $port;
$this->conn = NewADOConnection($db_type); $this->conn = NewADOConnection($db_type);
while ($try <= $retries) { while ($try <= $retries) {
if ($this->conn->NConnect($hostport,$user,$pass,$db_name)) { if ($this->conn->NConnect($hostport,$user,$pass,$db_name)) {
$this->conn = $this->conn; $this->conn = $this->conn;
return 0; return 0;
} }
$try++; $try++;
usleep(50000); usleep(50000);
} }
die("FATAL: Cannot connect to database server on '$host':'$port'. Please make sure you have specified a valid database name in 'includes/config.php'\n"); die("FATAL: Cannot connect to database server on '$host':'$port'. Please make sure you have specified a valid database name in 'includes/config.php'\n");
return 0; return 0;
} }
/** /**
* setDebug - enables or disabled debug mode * setDebug - enables or disabled debug mode
* *
* @param string $debug On or Off * @param string $debug On or Off
*/ */
function setDebug($debug) { function setDebug($debug) {
if ($debug == "On") { if ($debug == "On") {
$this->debug = TRUE; $this->debug = TRUE;
} else { } else {
$this->debug = FALSE; $this->debug = FALSE;
} }
} }
/** /**
* closeDB - close an open DB connection * setLogfile - set logfile path and name
* *
* @return string * @param string $logfile Logfile path and name
*/ */
function closeDB() { function setLogfile($logfile) {
if ($this->conn) { if ($logfile != "") {
return $this->conn->Close(); $this->logfile = $logfile;
} }
} }
/**
* execDB - execute a SQL statement against the DB via ADODB
*
* @param string $sql SQL statement to execute
* @return ADORecordSet
*/
function execDB($sql) {
$this->conn->debug = $this->debug;
$sql = $this->sanitizeSQL($sql);
$recordSet = &$this->conn->Execute($sql); /**
if (($recordSet) || ($this->conn->ErrorNo() == 0)) { * writeMSG
return($recordSet); *
} else { * @param mixed $msg
echo "<p style='font-size: 16px; font-weight: bold; color: red;'>Database Error (".$this->conn->ErrorNo().")</p>\n<p>".$this->conn->ErrorMsg()."</p>"; * @access public
//exit; * @return void
return ""; */
} function writeMSG($msg) {
}
if ($this->logfile != "") {
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, $msg);
}
fclose($loghandle);
} else {
echo "ERROR: Cannot open logfile: '".$logfile."' for writing. Falling back to STDOUT.\n";
echo $msg;
}
} else {
echo $msg;
}
}
/** /**
* fetchCellDB - execute a SQL query against the DB via ADODB and * closeDB - close an open DB connection
* return only the first column of the fist row found *
* or a specified column of the fist row found * @return string
* */
* @param string $sql SQL statement to execute function closeDB() {
* @param $column_name Column name to use instead of the first column if ($this->conn) {
* @return string Content of the cell as a single variable return $this->conn->Close();
*/ }
function fetchCellDB($sql, $column_name) { }
//$this->conn->debug = true;
$this->conn->debug = $this->debug;
$sql = $this->sanitizeSQL($sql);
if ($column_name != '') {
$this->conn->SetFetchMode(ADODB_FETCH_ASSOC);
} else {
$this->conn->SetFetchMode(ADODB_FETCH_NUM);
}
$recordSet = $this->conn->Execute($sql);
if (($recordSet) || ($this->conn->ErrorNo() == 0)) {
if (!$recordSet->EOF) {
if ($column_name != '') {
$column = $recordSet->fields[$column_name];
}else{
$column = $recordSet->fields[0];
}
$recordSet->close();
return($column);
}
} else {
echo "<p style='font-size: 16px; font-weight: bold; color: red;'>Database Error (".$this->conn->ErrorNo().")</p>\n<p>".$this->conn->ErrorMsg()."</p>";
exit;
}
}
/** /**
* fetchRowDB - execute a SQL query against the DB via ADODB * execDB - execute a SQL statement against the DB via ADODB
* and return only the first row found *
* * @param string $sql SQL statement to execute
* @param string $sql SQL statement to execute * @return ADORecordSet
* @return array First row of results as an associative array */
*/ function execDB($sql) {
function fetchRowDB($sql) { $this->conn->debug = $this->debug;
//$this->conn->debug = true; $sql = $this->sanitizeSQL($sql);
$this->conn->debug = $this->debug;
$sql = $this->sanitizeSQL($sql);
$this->conn->SetFetchMode(ADODB_FETCH_ASSOC); try {
$recordSet = $this->conn->Execute($sql); $recordSet = &$this->conn->Execute($sql);
} catch (exception $e) {
$this->writeMSG(adodb_backtrace($e->gettrace()));
exit;
}
if (($recordSet) || ($this->conn->ErrorNo() == 0)) { if (($recordSet) || ($this->conn->ErrorNo() == 0)) {
if (!$recordSet->EOF) { return($recordSet);
$recordFields = $recordSet->fields; }
$recordSet->close(); }
return($recordFields);
}
} else {
echo "<p style='font-size: 16px; font-weight: bold; color: red;'>Database Error (".$this->conn->ErrorNo().")</p>\n<p>".$this->conn->ErrorMsg()."</p>";
exit;
}
}
/** /**
* fetchArrayDB - execute a SQL query against the DB via ADODB * fetchCellDB - execute a SQL query against the DB via ADODB and
* and return results in an associative array. * return only the first column of the fist row found
* * or a specified column of the fist row found
* @param string $sql SQL statement to execute *
* @return array All results in an associative array * @param string $sql SQL statement to execute
*/ * @param $column_name Column name to use instead of the first column
function fetchArrayDB($sql) { * @return string Content of the cell as a single variable
//$this->conn->debug = true; */
$this->conn->debug = $this->debug; function fetchCellDB($sql, $column_name) {
$sql = $this->sanitizeSQL($sql); $this->conn->debug = $this->debug;
$sql = $this->sanitizeSQL($sql);
$recordArray = array(); if ($column_name != '') {
$this->conn->SetFetchMode(ADODB_FETCH_ASSOC); $this->conn->SetFetchMode(ADODB_FETCH_ASSOC);
$recordSet = &$this->conn->Execute($sql); } else {
$this->conn->SetFetchMode(ADODB_FETCH_NUM);
}
try {
$recordSet = $this->conn->Execute($sql);
} catch (exception $e) {
$this->writeMSG(adodb_backtrace($e->gettrace()));
exit;
}
if (($recordSet) || ($this->conn->ErrorNo() == 0)) { if (($recordSet) || ($this->conn->ErrorNo() == 0)) {
while ((!$recordSet->EOF) && ($recordSet)) { if (!$recordSet->EOF) {
$recordArray{sizeof($recordArray)} = $recordSet->fields; if ($column_name != '') {
$recordSet->MoveNext(); $column = $recordSet->fields[$column_name];
} }else{
$recordSet->close(); $column = $recordSet->fields[0];
return($recordArray); }
} else { $recordSet->close();
echo "<p style='font-size: 16px; font-weight: bold; color: red;'>Database Error (".$this->conn->ErrorNo().")</p>\n<p>".$this->conn->ErrorMsg()."</p>";
exit; return($column);
} }
} }
}
/** /**
* updateDB - execute a SQL update statement against the DB via ADODB * fetchRowDB - execute a SQL query against the DB via ADODB
* to update a record. If the record is not found, an insert * and return only the first row found
* statement is generated and executed. *
* * @param string $sql SQL statement to execute
* @param string $table The name of the table containing the record to be updated * @return array First row of results as an associative array
* @param array $cells An array of columnname/value pairs of the record to be updated */
* @param string $keys Name of the primary key function fetchRowDB($sql) {
* @param boolean $autoquote Use intelligent auto-quoting $this->conn->debug = $this->debug;
* @param ADOConnection $this->conn DB connection ID to run the SQL against $sql = $this->sanitizeSQL($sql);
* @return string Auto-increment ID if insert was performed
*/
function updateDB($table, $cells, $keys, $autoquote = TRUE) {
//$this->conn->debug = true;
$this->conn->debug = $this->debug;
$this->conn->Replace($table, $cells, $keys, $autoquote);
return $this->conn->Insert_ID(); $this->conn->SetFetchMode(ADODB_FETCH_ASSOC);
} try {
$recordSet = $this->conn->Execute($sql);
} catch (exception $e) {
$this->writeMSG(adodb_backtrace($e->gettrace()));
exit;
}
if (($recordSet) || ($this->conn->ErrorNo() == 0)) {
if (!$recordSet->EOF) {
$recordFields = $recordSet->fields;
$recordSet->close();
return($recordFields);
}
}
}
/** /**
* sanitizeSQL - removes unwanted chars in values passed for use in * fetchArrayDB - execute a SQL query against the DB via ADODB
* SQL statements * and return results in an associative array.
* *
* @param string $sql SQL expression to sanitize * @param string $sql SQL statement to execute
* @return string * @return array All results in an associative array
*/ */
function sanitizeSQL($sql) { function fetchArrayDB($sql) {
$sql = str_replace(";", "\;", $sql); $this->conn->debug = $this->debug;
$sql = str_replace("\n", "", $sql); $sql = $this->sanitizeSQL($sql);
$sql = str_replace("\r", "", $sql);
$sql = str_replace("\t", " ", $sql); $recordArray = array();
return $sql; $this->conn->SetFetchMode(ADODB_FETCH_ASSOC);
} try {
$recordSet = $this->conn->Execute($sql);
} catch (exception $e) {
$this->writeMSG(adodb_backtrace($e->gettrace()));
exit;
}
if (($recordSet) || ($this->conn->ErrorNo() == 0)) {
while ((!$recordSet->EOF) && ($recordSet)) {
$recordArray{sizeof($recordArray)} = $recordSet->fields;
$recordSet->MoveNext();
}
$recordSet->close();
return($recordArray);
}
}
/**
* updateDB - execute a SQL update statement against the DB via ADODB
* to update a record. If the record is not found, an insert
* statement is generated and executed.
*
* @param string $table The name of the table containing the record to be updated
* @param array $cells An array of columnname/value pairs of the record to be updated
* @param string $keys Name of the primary key
* @param boolean $autoquote Use intelligent auto-quoting
* @param ADOConnection $this->conn DB connection ID to run the SQL against
* @return string Auto-increment ID if insert was performed
*/
function updateDB($table, $cells, $keys, $autoquote = TRUE) {
$this->conn->debug = $this->debug;
try {
$this->conn->Replace($table, $cells, $keys, $autoquote);
} catch (exception $e) {
$this->writeMSG(adodb_backtrace($e->gettrace()));
exit;
}
return $this->conn->Insert_ID();
}
/**
* sanitizeSQL - removes unwanted chars in values passed for use in
* SQL statements
*
* @param string $sql SQL expression to sanitize
* @return string
*/
function sanitizeSQL($sql) {
$sql = str_replace(";", "\;", $sql);
$sql = str_replace("\n", "", $sql);
$sql = str_replace("\r", "", $sql);
$sql = str_replace("\t", " ", $sql);
return $sql;
}
} }

View File

@ -85,6 +85,7 @@ header("Pragma: no-cache");
//error_reporting(E_ALL); //error_reporting(E_ALL);
// ** Include generic code and external libraries ** // // ** Include generic code and external libraries ** //
include ($config["library_path"] . "/adodb5/adodb-exceptions.inc.php");
include ($config["library_path"] . "/adodb5/adodb.inc.php"); include ($config["library_path"] . "/adodb5/adodb.inc.php");
include_once($config["include_path"] . "/adodb.php"); include_once($config["include_path"] . "/adodb.php");
include_once($config["include_path"] . "/tsmmonitor.php"); include_once($config["include_path"] . "/tsmmonitor.php");
@ -94,11 +95,11 @@ include_once($config["include_path"] . "/polld.php");
$adodb = new ADOdb($config["db_host"], $config["db_port"], $config["db_user"], $config["db_password"], $config["db_name"], $config["db_type"]); $adodb = new ADOdb($config["db_host"], $config["db_port"], $config["db_user"], $config["db_password"], $config["db_name"], $config["db_type"]);
// ** instantiate TSMMonitor Class ** // // ** instantiate TSMMonitor Class ** //
$tsmmonitor = new TSMMonitor($adodb); if (isset($_SERVER['HTTP_USER_AGENT'])) $tsmmonitor = new TSMMonitor($adodb);
// check to see if this is a new installation // check to see if this is a new installation
$version = $adodb->fetchCellDB("SELECT confval FROM cfg_config WHERE confkey='version'", ''); $version = $adodb->fetchCellDB("SELECT confval FROM cfg_config WHERE confkey='version'", '');
if ($version != $config["tsm_monitor_version"] && basename($_SERVER['REQUEST_URI']) != 'install.php') { if (isset($_SERVER['HTTP_USER_AGENT']) && $version != $config["tsm_monitor_version"] && basename($_SERVER['REQUEST_URI']) != 'install.php') {
header("Location: install.php"); header("Location: install.php");
exit; exit;
} }

View File

@ -80,6 +80,8 @@ class PollD {
$this->loghandle = fopen($logfile[0]["confval"], 'at'); $this->loghandle = fopen($logfile[0]["confval"], 'at');
if (!$this->loghandle) { if (!$this->loghandle) {
echo "ERROR: Cannot open logfile: '".$logfile[0]["confval"]."' for writing. Falling back to STDOUT.\n"; echo "ERROR: Cannot open logfile: '".$logfile[0]["confval"]."' for writing. Falling back to STDOUT.\n";
} else {
$this->adodb->setLogfile($logfile[0]["confval"]);
} }
} }
$sql = "select confval from cfg_config WHERE `confkey`='path_dsmadmc'"; $sql = "select confval from cfg_config WHERE `confkey`='path_dsmadmc'";
@ -732,7 +734,7 @@ class PollD_MP {
// Check if PHP has pcntl_fork() enabled. // Check if PHP has pcntl_fork() enabled.
foreach ($funcs as $func) { foreach ($funcs as $func) {
if (!function_exists($func)){ if (!function_exists($func)) {
$func_ena = false; $func_ena = false;
array_push($func_miss, $func); array_push($func_miss, $func);
} }
@ -803,19 +805,23 @@ class PollD_MP {
} }
if ($this->debuglevel >= $ilevel) { if ($this->debuglevel >= $ilevel) {
if ($loghandle = fopen($this->logfile, 'a')) { if ($this->logfile != "") {
$starttime = microtime(); if ($loghandle = fopen($this->logfile, 'a')) {
do { $starttime = microtime();
$lock = flock($loghandle, LOCK_EX); do {
if (!$lock) usleep(round(rand(0, 100) * 1000)); $lock = flock($loghandle, LOCK_EX);
} while (!$lock && ((microtime() - $starttime) < 1000)); if (!$lock) usleep(round(rand(0, 100) * 1000));
} while (!$lock && ((microtime() - $starttime) < 1000));
if ($lock) { if ($lock) {
fwrite($loghandle, $level.": ".$msg); fwrite($loghandle, $level.": ".$msg);
}
fclose($loghandle);
} else {
echo "ERROR: Cannot open logfile: '".$logfile."' for writing. Falling back to STDOUT.\n";
echo $level.": ".$msg;
} }
fclose($loghandle);
} else { } else {
echo "ERROR: Cannot open logfile: '".$logfile."' for writing. Falling back to STDOUT.\n";
echo $level.": ".$msg; echo $level.": ".$msg;
} }
} }
@ -1302,7 +1308,7 @@ class PollD_MP {
if ($this->isEnabled()) { if ($this->isEnabled()) {
// Main loop for dispatcher // Main loop for dispatcher
while(true) { 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->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->logfile);
$this->updateJoblist($this->adodb); $this->updateJoblist($this->adodb);
$query = "SELECT * FROM job_list"; $query = "SELECT * FROM job_list";
$jobs = $this->adodb->fetchArrayDB($query); $jobs = $this->adodb->fetchArrayDB($query);
@ -1352,7 +1358,7 @@ class PollD_MP {
$this->child_pid = posix_getpid(); $this->child_pid = posix_getpid();
$timestamp = time(); $timestamp = time();
$this->writeMSG("Worker(".$this->child_pid.") ".sprintf('%-16s', $server)." Timestamp for this run is $timestamp.\n", INFO); $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->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->logfile);
$this->setPollDStatus($server, "running", $this->child_pid, $timestamp, ""); $this->setPollDStatus($server, "running", $this->child_pid, $timestamp, "");
// Process job // Process job