Modify query_error() to log errors to a database table instead of displaying them on the screen. This should
let us more easily debug difficult or intermittent issues that users may not report. Add a cron to report logged errors to appdb admins every night. Implement some basic unit tests for the new error logging code
This commit is contained in:
@@ -78,7 +78,8 @@ orphanSessionMessagesCheck();
|
||||
/* check and purge any expired sessions from the session_list table */
|
||||
orphanSessionListCheck();
|
||||
|
||||
|
||||
/* report error log entries to admins and flush the error log after doing so */
|
||||
reportErrorLogEntries();
|
||||
|
||||
|
||||
/* Users that are unwarned and inactive since $iMonths */
|
||||
@@ -228,3 +229,11 @@ function orphanSessionListCheck()
|
||||
$sQuery = "DELETE from session_list where TO_DAYS(NOW()) - TO_DAYS(stamp) > ?";
|
||||
$hResult = query_parameters($sQuery, SESSION_DAYS_TO_EXPIRE + 2);
|
||||
}
|
||||
|
||||
function reportErrorLogEntries()
|
||||
{
|
||||
error_log::mail_admins_error_log();
|
||||
error_log::flush();
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
92
include/error_log.php
Normal file
92
include/error_log.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
define(ERROR_SQL, "sql_error");
|
||||
define(ERROR_GENERAL, "general_error");
|
||||
|
||||
class error_log
|
||||
{
|
||||
function log_error($sErrorType, $sLogText)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
/* dump the contents of $_REQUEST and $aClean to a variable */
|
||||
/* so we can output that to the log entry. it should make it much easier */
|
||||
/* to determine when and where the error took place */
|
||||
ob_start();
|
||||
echo "REQUEST:\n";
|
||||
var_dump($_REQUEST);
|
||||
echo "aClean:\n";
|
||||
var_dump($aClean);
|
||||
$sRequestText = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$sQuery = 'INSERT INTO error_log (submitTime, userid, type, log_text, request_text, deleted) '.
|
||||
"VALUES(?, '?', '?', '?', '?', '?')";
|
||||
$hResult = query_parameters($sQuery,
|
||||
"NOW()",
|
||||
$_SESSION['current']->iUserId,
|
||||
$sErrorType,
|
||||
$sLogText,
|
||||
$sRequestText,
|
||||
'0');
|
||||
}
|
||||
|
||||
function getEntryCount()
|
||||
{
|
||||
$sQuery = "SELECT count(*) as cnt FROM error_log WHERE deleted = '0'";
|
||||
$hResult = query_parameters($sQuery);
|
||||
$oRow = mysql_fetch_object($hResult);
|
||||
return $oRow->cnt;
|
||||
}
|
||||
|
||||
/* purge all of the current entries from the error log */
|
||||
function flush()
|
||||
{
|
||||
$sQuery = "UPDATE error_log SET deleted='1'";
|
||||
$hResult = query_parameters($sQuery);
|
||||
|
||||
if($hResult) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
function mail_admins_error_log()
|
||||
{
|
||||
$sSubject = "Appdb error log\r\n";
|
||||
$sEmail = User::get_notify_email_address_list(null, null); /* get list admins */
|
||||
|
||||
$sQuery = "SELECT * from error_log WHERE deleted='0' ORDER BY submitTime";
|
||||
$hResult = query_parameters($sQuery);
|
||||
|
||||
$bEmpty = false;
|
||||
if(mysql_num_rows($hResult) == 0)
|
||||
$bEmpty = true;
|
||||
|
||||
$sMsg = "Log entries:\r\n";
|
||||
$sMsg.= "\r\n";
|
||||
|
||||
$sMsg.= "Submit time userid type\r\n";
|
||||
$sMsg.= "log_text\r\n";
|
||||
$sMsg.= "request_text\r\n";
|
||||
$sMsg.="----------------------------------\r\n\r\n";
|
||||
|
||||
/* append each log entry to $sMsg */
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
{
|
||||
$sMsg.=$oRow->submitTime." ".$oRow->userid." ".$oRow->type."\r\n";
|
||||
$sMsg.= "---------------------\r\n";
|
||||
$sMsg.=$oRow->log_text."\r\n";
|
||||
$sMsg.= "---------------------\r\n";
|
||||
$sMsg.=$oRow->request_text."\r\n\r\n";
|
||||
}
|
||||
|
||||
/* if we had no entries we should indicate */
|
||||
/* that the error log is empty */
|
||||
if($bEmpty)
|
||||
$sMsg = "The error log is empty.\r\n";
|
||||
|
||||
if($sEmail)
|
||||
mail_appdb($sEmail, $sSubject, $sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -11,6 +11,7 @@ require(BASE."include/user.php");
|
||||
require(BASE."include/session.php");
|
||||
require(BASE."include/menu.php");
|
||||
require(BASE."include/html.php");
|
||||
require(BASE."include/error_log.php");
|
||||
require(BASE."include/query.php");
|
||||
|
||||
/* if magic quotes are enabled make sure the user disables them */
|
||||
|
||||
@@ -113,11 +113,10 @@ function query_bugzilladb($sQuery,$sComment="")
|
||||
|
||||
function query_error($sQuery, $sComment="")
|
||||
{
|
||||
$sStatusMessage = "<p><b>Database Error!</b><br />";
|
||||
$sStatusMessage .= "Query: ".$sQuery."<br />";
|
||||
$sStatusMessage .= $sComment ? $sComment."<br />" : "";
|
||||
$sStatusMessage .= mysql_error()."</p>\n";
|
||||
addmsg($sStatusMessage, "red");
|
||||
$sStatusMessage = "<p><b>An internal error has occurred and has been logged and reported to appdb admins</b></p>";
|
||||
addmsg($sStatusMessage);
|
||||
|
||||
error_log::log_error(ERROR_SQL, "Query: '".$sQuery."' mysql_error(): '".mysql_error()."' comment: '".$sComment."'");
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -30,3 +30,5 @@ mysql -p -u root < buglinks.sql
|
||||
echo Adding monitors
|
||||
mysql -p -u root < monitors.sql
|
||||
|
||||
echo Creating error logging tables
|
||||
mysql -p -u root < error_log.sql
|
||||
|
||||
14
tables/error_log.sql
Normal file
14
tables/error_log.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
use apidb;
|
||||
|
||||
drop table if exists error_log;
|
||||
|
||||
create table error_log (
|
||||
id int not null auto_increment,
|
||||
submitTime datetime,
|
||||
userid int not null default '0',
|
||||
type enum('sql_error', 'general_error'),
|
||||
log_text text,
|
||||
request_text text,
|
||||
deleted bool,
|
||||
key(id)
|
||||
);
|
||||
@@ -12,5 +12,7 @@ echo "\n";
|
||||
include_once("test_query.php");
|
||||
echo "\n";
|
||||
include_once("test_image.php");
|
||||
echo "\n";
|
||||
include_once("test_error_log.php");
|
||||
|
||||
?>
|
||||
40
unit_test/test_error_log.php
Normal file
40
unit_test/test_error_log.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
require_once("path.php");
|
||||
require_once(BASE."include/incl.php");
|
||||
|
||||
function test_error_log_log_error()
|
||||
{
|
||||
error_log::log_error(ERROR_SQL, "This is a sql error");
|
||||
error_log::log_error(ERROR_GENERAL, "This is a general error");
|
||||
|
||||
/* make sure the error log count matches what we expect */
|
||||
$iExpected = 2;
|
||||
$iActual = error_log::getEntryCount();
|
||||
if($iActual != $iExpected)
|
||||
{
|
||||
echo "Expected error_log::getEntryCount() of ".$iExpected." got ".$iActual;
|
||||
return false;
|
||||
}
|
||||
|
||||
error_log::flush(); /* flush the error log */
|
||||
|
||||
/* make sure the error log count matches what we expect */
|
||||
$iExpected = 0;
|
||||
$iActual = error_log::getEntryCount();
|
||||
if($iActual != $iExpected)
|
||||
{
|
||||
echo "Expected error_log::getEntryCount() of ".$iExpected." got ".$iActual;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if(!test_error_log_log_error())
|
||||
echo "test_error_log_log_error() failed!\n";
|
||||
else
|
||||
echo "test_error_log_log_error() passed\n";
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user