Created
March 4, 2011 05:08
-
-
Save chrisbloom7/854208 to your computer and use it in GitHub Desktop.
Some standard debugging functions I use in almost every project. Include this file after the main config file has been loaded.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This should probably be ported to a custom class... | |
// DEBUGGING - set to TRUE to force debugging or comment out to use dynamic | |
// debugging. The debugging behaviour is unreliable if this is set to FALSE | |
// define("X_GLOBAL_DEBUG", TRUE); | |
// LOG_DIR needs to be defined here rather than in the local config file because we | |
// may need access to it from pages where the local conf hasn't been loaded yet. | |
define('LOG_DIR', dirname(__FILE__) . '/../../logs'); | |
// Define debugging levels. Set constant X_LOGVAR_LEVEL to one of these integer | |
// values in the main config file. | |
define('X_LOGVAR_NONE', 0); | |
define('X_LOGVAR_ERROR', 1); | |
define('X_LOGVAR_WARNING', 2); | |
define('X_LOGVAR_INFO', 3); | |
// Override error logging defaults | |
ini_set('error_log', LOG_DIR . '/php_error.log'); | |
ini_set('log_errors', 'On'); | |
ini_set('html_errors', 'Off'); | |
ini_set('display_errors', 'Off'); | |
// Setup stricter error reporting if necessary | |
if ((defined('X_GLOBAL_DEBUG') && X_GLOBAL_DEBUG == true) //Forced debugging via constant | |
|| (isset($_REQUEST['X_GLOBAL_DEBUG']) && $_REQUEST['X_GLOBAL_DEBUG'] == 'foo') //Dynamic debugging via request parameter or cookie | |
) { | |
error_reporting(E_ALL); | |
if (!defined('X_GLOBAL_DEBUG')) { | |
define('X_GLOBAL_DEBUG', true); | |
} | |
} else { | |
error_reporting(E_ALL ^ E_NOTICE); | |
if (!defined('X_GLOBAL_DEBUG')) { | |
define('X_GLOBAL_DEBUG', false); | |
} | |
} | |
// Custom error reporting with backtrace | |
function log_error_backtrace($errno, $errstr, $errfile, $errline, $errcontext) | |
{ | |
if (!(error_reporting() & $errno)) return; | |
switch ($errno) { | |
case E_WARNING: | |
case E_USER_WARNING: | |
case E_STRICT: | |
case E_NOTICE: | |
case E_USER_NOTICE: | |
$type = 'warning'; | |
$fatal = false; | |
break; | |
default: | |
$type = 'fatal error'; | |
$fatal = true; | |
break; | |
} | |
$log = array(); | |
foreach (array_reverse(debug_backtrace()) as $item) { | |
$log[] = (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()'; | |
} | |
LOGVAR($log, 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline, X_LOGVAR_ERROR); | |
if (X_GLOBAL_DEBUG || ini_get('display_errors')) { | |
PRINTVAR($log, 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline, (php_sapi_name() == 'cli')); | |
} | |
if ($fatal) exit(1); | |
} | |
// Comment out next line to disable custom error handler | |
set_error_handler('log_error_backtrace'); | |
// Set X_GLOBAL_DEBUG_PLAIN to true if we are in a command-line-only environment | |
if (!isset($X_GLOBAL_DEBUG_PLAIN)) { | |
$X_GLOBAL_DEBUG_PLAIN = false; | |
} | |
// The functions | |
function GETVAR($var, $label = "") | |
{ | |
$output = "<pre style=\"border: 1px solid #999; background-color: #f7f7f7; color: #000; overflow: auto; width: auto; text-align: left; padding: 1em;\">" . ((strlen(trim($label))) ? htmlentities($label) . "\n===================\n" : "") . htmlentities(print_r($var, true)) . "</pre>"; | |
return $output; | |
} | |
function GETVARPLAIN($var, $label = "") | |
{ | |
$output = '' . ((strlen(trim($label))) ? $label . "\n===================\n" : "") . print_r($var, true) . "\n\n"; | |
return $output; | |
} | |
function PRINTVAR($var, $label = "", $plain = false) | |
{ | |
global $X_GLOBAL_DEBUG_PLAIN; | |
print (($plain || $X_GLOBAL_DEBUG_PLAIN) ? GETVARPLAIN($var, $label) : GETVAR($var, $label)); | |
} | |
function PRINTVARD($var, $label = "", $plain = false) | |
{ | |
global $X_GLOBAL_DEBUG_PLAIN; | |
die(($plain || $X_GLOBAL_DEBUG_PLAIN) ? GETVARPLAIN($var, $label) : GETVAR($var, $label)); | |
} | |
function LOGVAR($var, $label = "", $level = X_LOGVAR_INFO, $group = false) | |
{ | |
if (!defined('X_LOGVAR_LEVEL')) { | |
if (X_GLOBAL_DEBUG) { | |
$X_LOGVAR_LEVEL = X_LOGVAR_INFO; | |
} else { | |
$X_LOGVAR_LEVEL = X_LOGVAR_WARNING; | |
} | |
} else { | |
$X_LOGVAR_LEVEL = X_LOGVAR_LEVEL; | |
} | |
if (X_GLOBAL_DEBUG) { | |
PRINTVAR($var, $label); | |
} elseif (intval($level) > $X_LOGVAR_LEVEL) { | |
return; | |
} else { | |
$message = GETVARPLAIN($var, $label); | |
if (X_LOGVAR_USE_DATABASE) { | |
debug_log_to_database($message, $level, ($group) ? $group : 'debug'); | |
} | |
else { | |
$uri = $_SERVER['REQUEST_URI']; | |
if (!empty($_SERVER['QUERY_STRING'])) $uri.= '?' . $_SERVER['QUERY_STRING']; | |
$data = sprintf("[%s] Request URI: %s\n-------------------------------------------------\n%s", gmdate('d-M-Y H:i:s') . ' GMT', $uri, $message); | |
debug_write_log(($group) ? $group : 'debug', $data); | |
} | |
} | |
} | |
function LOGVARD($var, $label = "", $group = false) | |
{ | |
if (X_GLOBAL_DEBUG) { | |
PRINTVARD($var, $label); | |
} else { | |
LOGVAR($var, $label, 99, $group); | |
PRINTVARD('A fatal error has occured and has been logged.'); | |
} | |
} | |
function debug_write_log($logfile, $data) | |
{ | |
$filename = sprintf("%s/%s.%s.%s.log", LOG_DIR, $logfile, date('Y-m-d'), str_replace('.', '_', $_SERVER['SERVER_ADDR'])); | |
$fp = @fopen($filename, 'a+b'); | |
if ($fp === false || !is_writeable($filename)) { | |
PRINTVARD('Could not open log file for writing'); | |
} | |
fwrite($fp, $data); | |
fclose($fp); | |
} | |
/** | |
* To enable tracking of data across requests, add the following to your config file: | |
* | |
// Though not neccessarily a configurable option, this is the best place to include this | |
// so that we have access to the COOKIE_HOST constant. | |
if (empty($_COOKIE['x_logvar_id']) && !headers_sent()) { | |
$x_logvar_id = base_convert(mt_rand(0, 0x38E38E3), 10, 36) . '-' . microtime(TRUE); | |
setcookie("x_logvar_id", $x_logvar_id, 0, '/', '' . COOKIE_HOST, FALSE); | |
setcookie("x_logvar_id", $x_logvar_id, 0, '/', '.' . COOKIE_HOST, FALSE); | |
} | |
*/ | |
function debug_log_to_database($message, $level, $group) { | |
$log_data = array( | |
'message' => $message, | |
'level' => $level, | |
'group' => $group, | |
'timestamp' => gmdate('Y-m-d H:i:s'), | |
'request_environment' => GETVARPLAIN(array( | |
'SERVER' => $_SERVER, | |
'GET' => $_GET, | |
'POST' => $_POST, | |
'FILES' => $_FILES, | |
'COOKIE' => $_COOKIE, | |
'SESSION' => $_SESSION, | |
'REQUEST' => $_REQUEST, | |
'ENV' => $_ENV | |
)), | |
'remote_address' => ((!empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : ''), | |
'uri' => ((!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : ''), | |
'server_address' => ((!empty($_SERVER['SERVER_ADDR'])) ? $_SERVER['SERVER_ADDR'] : ''), | |
'x_logvar_id' => ((!empty($_COOKIE['x_logvar_id'])) ? $_COOKIE['x_logvar_id'] : '') | |
); | |
if (function_exists('some_insert_function')) { | |
/** | |
* Add code to insert the $log_data array into the database. If we were using ADOdb, it might | |
* look like this: | |
* | |
global $ADODB_QUOTE_FIELDNAMES; | |
$old_ADODB_QUOTE_FIELDNAMES = $ADODB_QUOTE_FIELDNAMES; | |
// Make sure ADOdb quotes the field names | |
$ADODB_QUOTE_FIELDNAMES = TRUE; | |
some_insert_function('_debug_log', $log_data); | |
$ADODB_QUOTE_FIELDNAMES = $old_ADODB_QUOTE_FIELDNAMES; | |
unset($old_ADODB_QUOTE_FIELDNAMES); | |
*/ | |
} | |
// If all else fails: | |
else { | |
debug_write_log($group, $log_data); | |
} | |
} | |
$X_GLOBAL_BENCHMARK_LAST_TIME = $X_GLOBAL_BENCHMARK_TIME = microtime(true); | |
function benchmark($label = false, $save_to_log = false, $group = false) | |
{ | |
if (!$label) { | |
$trace = debug_backtrace(); | |
if (isset($trace[1])) | |
{ | |
$label = (empty($trace[1]['function'])) ? '' : "{$trace[1]['function']}::"; | |
$label .= "{$trace[0]['file']}::{$trace[0]['line']}"; | |
} | |
} | |
$btime = microtime(true); | |
LOGVAR(array( | |
'benchmark' => $btime - $GLOBALS['X_GLOBAL_BENCHMARK_TIME'], | |
'delta' => $btime - $GLOBALS['X_GLOBAL_BENCHMARK_LAST_TIME'] | |
), $label, X_LOGVAR_INFO, $group); | |
if ($save_to_log) { | |
debug_write_log(($group) ? $group : 'benchmark', sprintf("[%s]\t%s\t%s\n", $label, gmdate('d-M-Y H:i:s') , $btime - $GLOBALS['X_GLOBAL_BENCHMARK_TIME'])); | |
} | |
$GLOBALS['X_GLOBAL_BENCHMARK_LAST_TIME'] = $btime; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment