Skip to content

Instantly share code, notes, and snippets.

@mca-gif
Created May 9, 2014 18:45
Show Gist options
  • Save mca-gif/a2ad7694bfa12b7b47ec to your computer and use it in GitHub Desktop.
Save mca-gif/a2ad7694bfa12b7b47ec to your computer and use it in GitHub Desktop.
General purpose Debug logger, with multiple levels and file level disabling
<?php
/**
* Debug provides an API to save to common log file throughout the entire application
* All effort should be made to keep this file as portable to any application as possible
*
* Currently 4 levels of log entries exist: Errors, Warnings, Info, Trace.
* Errors = Conditions which occur and are possibly not recoverable from a user perspective. (i.e. Database will not connect)
* Warnings = Conditions which may not be favorable, but are recoverable. (i.e. Session information not available)
* Info = Any other information which does not indicate an issue to fix. (i.e. Early terminiation of script due to redirect)
* Trace = Position information and programmer fluff. These should be inserted during coding, and removed when done. (i.e. Entered function xyz() )
*
* Usage:
* By default Debug is configured to only display errors, this can be overridden with Debug::$debugLevel setting to any
* of the constants: DebugLevelNone, DebugLevelErrors, DebugLevelWarnings, DebugLevelInfo, DebugLevelTrace.
*
* When a log level is set, all levels lower than it will be enabled too. (i.e. Enabling Info turns on Warnings and Errors)
*
* Create an entry with Debug::error(), Debug::warn(), Debug::info(), Debug::trace(). Each takes a string as input.
* The filename and position of the calling function will automatically be included after the message.
* The filename of PHP_SELF will be prepended as well.
*
* Location:
* All debug messages are sent to the PHP error_log() function for handling. The default configuration will
* have messages directed to the webserver's error.log file.
*
* Enable / Disable a File:
* By default all files have logging enabled, but if you wish to disable logging for a specific file
* calling Debug::disableFile() will stop all future calls to Debug from being outputed to the file.
* Simply renable the file with Debug::enableFile()
* Neither function accepts an argument, the filename will be established from the backtrace
*
* EVEN IF A FILE IS DIABLED, ANY ERROR LEVEL LOG WILL BE WRITTEN TO THE FILE
*/
class Debug
{
const DebugLevelNone = 0;
const DebugLevelErrors = 1;
const DebugLevelWarnings = 2;
const DebugLevelInfo = 4;
const DebugLevelTrace = 8;
public static $debugLevel = self::DebugLevelTrace;
private static $logHandle = null;
private static $fileDisabledArray = array();
/**
* Handles writing data to the log file.
*
* This function will not write to the log if the file that called Debug has also disabled logging.
*
* @param string $string The value to be written.
* @param bool $alwaysPrint When set to true, this overrides any disabled logging.
*/
private static function output($level, $string, $alwaysPrint = false)
{
$bt_info = self::resolveCallerInfo();
if ( $alwaysPrint || !isset(self::$fileDisabledArray[$bt_info['file']]) ) {
// If the $string is actually an object, use print_r to serialize the object.
if ( gettype($string) == 'object' ) {
$string = print_r($string, true);
}
error_log(
sprintf("[%s] %s: %s in %s at line %d\n",
$level,
$_SERVER['PHP_SELF'],
$string, $bt_info['file'],
$bt_info['line']
)
);
}
}
/**
* Returns information about the file, line, function, and class that originall called Debug.
*
* This is necessary because the top of the backtrace stack is clobbered by Debug, and later we
* will want to know where we came from; not where we are now.
*/
private static function resolveCallerInfo()
{
$bt = debug_backtrace();
$i = 0;
do {
$bt_funcClass = $bt[$i]['class'];
$bt_funcFunction = $bt[$i]['function'];
$bt_funcFile = $bt[$i]['file'];
$bt_funcLine = $bt[$i]['line'];
$i++;
} while ($bt_funcFile == __FILE__ && $i < count($bt) );
// Chop off excess file path
$bt_funcFile = str_replace($_SERVER['DOCUMENT_ROOT'],'', $bt_funcFile);
return array('file' => $bt_funcFile, 'line' => $bt_funcLine, 'function' => $bt_funcFunction, 'class' => $bt_funcClass);
}
public static function trace($string)
{
if (self::$debugLevel == 8) {
self::output('TRACE', $string);
}
}
public static function info($string)
{
if (self::$debugLevel >= 4) {
self::output('INFO', $string);
}
}
public static function warn($string)
{
if (self::$debugLevel >= 2) {
self::output('WARNING', $string);
}
}
public static function error($string)
{
if (self::$debugLevel >= 1 ) {
self::output('ERROR', $string, true);
}
}
public static function disableFile()
{
$bt_info = self::resolveCallerInfo();
$filename = $bt_info['file'];
self::$fileDisabledArray[$filename] = true;
}
public static function enableFile()
{
$bt_info = self::resolveCallerInfo();
$filename = $bt_info['file'];
unset(self::$fileDisabledArray[$filename]);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment