git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@2147 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
230 lines
8.5 KiB
PHP
230 lines
8.5 KiB
PHP
<?php
|
|
/** DomFramework
|
|
@package domframework
|
|
@author Dominique Fournier <dominique@fournier38.fr> */
|
|
|
|
/** The logger class permit to log the informations from the soft
|
|
It allow to debug too */
|
|
class logger
|
|
{
|
|
/* The logger class can be used with :
|
|
$d=new logger;
|
|
$d->timezone = "Europe/Paris";
|
|
$d->logtype="display|file";
|
|
$d->logfile="/tmp/toto.log";
|
|
$d->logwrite ("Super log default");
|
|
$d->logwrite ("Super log DEBUG", $d::DEBUG);
|
|
$d->logwrite ("Super log NOTICE", $d::NOTICE); */
|
|
// TODO : Add SQL support
|
|
/** The method to log.
|
|
Can be display, file, syslog
|
|
Can be merged with a pipe : "display|syslog|file"*/
|
|
public $logtype = "display";
|
|
/** For logtype=file, the filename to use */
|
|
public $logfile = FALSE;
|
|
/** Timezone use to save the logs */
|
|
public $timezone = "UTC";
|
|
/** Minimum log level in the logs */
|
|
public $loglevelmin = LOG_NOTICE;
|
|
/** In Syslog mode, the facility to use
|
|
See http://fr2.php.net/manual/en/function.openlog.php for $syslogFacility */
|
|
public $syslogFacility = LOG_USER;
|
|
/** In Syslog, prefix the log by the text */
|
|
public $syslogPrefix = FALSE;
|
|
/** Remove X entries of backtrace to see the right file generating the error
|
|
*/
|
|
public $backTraceSkip = 0;
|
|
|
|
/** The priorities which can be used in the priorities
|
|
LOG_EMERG system is unusable
|
|
LOG_ALERT action must be taken immediately
|
|
LOG_CRIT critical conditions
|
|
LOG_ERR error conditions
|
|
LOG_WARNING warning conditions
|
|
LOG_NOTICE normal, but significant, condition
|
|
LOG_INFO informational message
|
|
LOG_DEBUG debug-level message */
|
|
private $priorities = array (LOG_EMERG => "EMERG",
|
|
LOG_ALERT => "ALERT",
|
|
LOG_CRIT => "CRITICAL",
|
|
LOG_ERR => "ERROR",
|
|
LOG_WARNING => "WARNING",
|
|
LOG_NOTICE => "NOTICE",
|
|
LOG_INFO => "INFO",
|
|
LOG_DEBUG => "DEBUG");
|
|
|
|
/** Store a new message log in the log manager defined by $logtype
|
|
The message can be multiple types. An array will be stored in textual form
|
|
but it will accept only one depth.
|
|
The $message is not fixed, you can pass the number of parameters you want
|
|
@param integer|null $priority Priority to use
|
|
@param mixed ...$message Message to log */
|
|
public function log ($priority=LOG_NOTICE, $message)
|
|
{
|
|
if (! is_int ($priority))
|
|
{
|
|
switch ($priority)
|
|
{
|
|
case "LOG_EMERG": $priority = LOG_EMERG; break;
|
|
case "LOG_ALERT": $priority = LOG_ALERT; break;
|
|
case "LOG_CRIT": $priority = LOG_CRIT; break;
|
|
case "LOG_ERR": $priority = LOG_ERR; break;
|
|
case "LOG_WARNING": $priority = LOG_WARNING; break;
|
|
case "LOG_NOTICE": $priority = LOG_NOTICE; break;
|
|
case "LOG_INFO": $priority = LOG_INFO; break;
|
|
case "LOG_DEBUG": $priority = LOG_DEBUG; break;
|
|
}
|
|
}
|
|
if (! is_int ($this->loglevelmin))
|
|
{
|
|
switch ($this->loglevelmin)
|
|
{
|
|
case "LOG_EMERG": $this->loglevelmin = LOG_EMERG; break;
|
|
case "LOG_ALERT": $this->loglevelmin = LOG_ALERT; break;
|
|
case "LOG_CRIT": $this->loglevelmin = LOG_CRIT; break;
|
|
case "LOG_ERR": $this->loglevelmin = LOG_ERR; break;
|
|
case "LOG_WARNING": $this->loglevelmin = LOG_WARNING; break;
|
|
case "LOG_NOTICE": $this->loglevelmin = LOG_NOTICE; break;
|
|
case "LOG_INFO": $this->loglevelmin = LOG_INFO; break;
|
|
case "LOG_DEBUG": $this->loglevelmin = LOG_DEBUG; break;
|
|
}
|
|
}
|
|
if ($this->loglevelmin < $priority)
|
|
return;
|
|
$backtrace = debug_backtrace();
|
|
for ($i = 0 ; $i <= $this->backTraceSkip ; $i++)
|
|
$back = array_shift ($backtrace);
|
|
$msg = "";
|
|
if (isset ($_SERVER["HTTP_X_FORWARDED_FOR"]))
|
|
$msg .= "[".$_SERVER["HTTP_X_FORWARDED_FOR"]."] ";
|
|
elseif (isset ($_SERVER["REMOTE_ADDR"]))
|
|
$msg .= "[".$_SERVER["REMOTE_ADDR"]."] ";
|
|
|
|
// The messages are all the parameters of the function except the first,
|
|
// which is the priority
|
|
$messages = func_get_args ();
|
|
array_shift ($messages);
|
|
// Convert each part of message to text
|
|
foreach ($messages as $m)
|
|
{
|
|
if (is_array ($m))
|
|
{
|
|
$msg .= "[";
|
|
foreach ($m as $key=>$val)
|
|
{
|
|
if (is_array ($val))
|
|
{
|
|
foreach ($val as $key2=>$val2)
|
|
{
|
|
$msg .= "$key2=>$val2,";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$msg .= "$key=>$val,";
|
|
}
|
|
}
|
|
$msg .= "]";
|
|
}
|
|
else
|
|
{
|
|
$msg .= $m;
|
|
}
|
|
}
|
|
|
|
// Add the filename which generate the error
|
|
$msg .= " [".basename ($back["file"]).":".$back["line"]."]";
|
|
|
|
$logsType = explode ("|", $this->logtype);
|
|
if (in_array ("display", $logsType))
|
|
$this->logdisplay ($msg, $priority);
|
|
if (in_array ("file", $logsType))
|
|
$this->logfile ($msg, $priority);
|
|
if (in_array ("syslog", $logsType))
|
|
$this->logsyslog ($msg, $priority);
|
|
}
|
|
|
|
/** Log $message on file
|
|
@param string $message Message to log
|
|
@param integer|null $priority Priority to use */
|
|
private function logfile ($message, $priority)
|
|
{
|
|
if ($this->logfile === FALSE)
|
|
throw new Exception ("Undefined file where logging");
|
|
if (!file_exists ($this->logfile))
|
|
{
|
|
if (! is_dir (dirname ($this->logfile)))
|
|
throw new Exception ("You must create the ".dirname ($this->logfile).
|
|
"directory");
|
|
if (! is_writable (dirname ($this->logfile)))
|
|
throw new Exception ("The directory ".dirname ($this->logfile)." must"
|
|
." be writable to create log file");
|
|
}
|
|
elseif (!is_writable ($this->logfile))
|
|
{
|
|
if (function_exists ("posix_geteuid"))
|
|
$user = posix_geteuid ();
|
|
elseif (getenv('USERNAME') !== FALSE)
|
|
$user = getenv('USERNAME');
|
|
else
|
|
$user = "";
|
|
throw new Exception ("Logfile $this->logfile is not writable for user ".
|
|
$user);
|
|
}
|
|
|
|
ini_set ("date.timezone", $this->timezone);
|
|
$message = date ("Y/m/d H:i:s")." [".$this->priorities[$priority]."] ".
|
|
$message."\n";
|
|
file_put_contents ($this->logfile, $message, FILE_APPEND);
|
|
}
|
|
|
|
/** Log $message on screen with adding date. Add the HTML flags if not in CLI.
|
|
@param string $message Message to log
|
|
@param integer|null $priority Priority to use */
|
|
private function logdisplay ($message, $priority)
|
|
{
|
|
if (php_sapi_name () !== "cli")
|
|
echo "<tt>";
|
|
ini_set ("date.timezone", $this->timezone);
|
|
$message = date ("Y/m/d H:i:s")." [".$this->priorities[$priority]."] ".
|
|
$message;
|
|
echo "$message";
|
|
if (php_sapi_name () !== "cli")
|
|
echo "</tt><br/>";
|
|
echo "\n";
|
|
}
|
|
|
|
/** Log $message on syslog
|
|
@param string $message Message to log
|
|
@param integer|null $priority Priority to use */
|
|
private function logsyslog ($message, $priority)
|
|
{
|
|
if (is_string ($this->syslogFacility))
|
|
{
|
|
switch ($this->syslogFacility)
|
|
{
|
|
case "LOG_AUTH": $this->syslogFacility=LOG_AUTH; break;
|
|
case "LOG_AUTHPRIV": $this->syslogFacility=LOG_AUTHPRIV; break;
|
|
case "LOG_DAEMON": $this->syslogFacility=LOG_DAEMON; break;
|
|
case "LOG_KERN": $this->syslogFacility=LOG_KERN; break;
|
|
case "LOG_LOCAL0": $this->syslogFacility=LOG_LOCAL0; break;
|
|
case "LOG_LOCAL1": $this->syslogFacility=LOG_LOCAL1; break;
|
|
case "LOG_LOCAL2": $this->syslogFacility=LOG_LOCAL2; break;
|
|
case "LOG_LOCAL3": $this->syslogFacility=LOG_LOCAL3; break;
|
|
case "LOG_LOCAL4": $this->syslogFacility=LOG_LOCAL4; break;
|
|
case "LOG_LOCAL5": $this->syslogFacility=LOG_LOCAL5; break;
|
|
case "LOG_LOCAL6": $this->syslogFacility=LOG_LOCAL6; break;
|
|
case "LOG_LOCAL7": $this->syslogFacility=LOG_LOCAL7; break;
|
|
case "LOG_LPR": $this->syslogFacility=LOG_LPR; break;
|
|
case "LOG_MAIL": $this->syslogFacility=LOG_MAIL; break;
|
|
case "LOG_NEWS": $this->syslogFacility=LOG_NEWS; break;
|
|
case "LOG_SYSLOG": $this->syslogFacility=LOG_SYSLOG; break;
|
|
case "LOG_USER": $this->syslogFacility=LOG_USER; break;
|
|
case "LOG_UUCP": $this->syslogFacility=LOG_UUCP; break;
|
|
}
|
|
}
|
|
openlog ($this->syslogPrefix, NULL, $this->syslogFacility);
|
|
syslog ($priority, $message);
|
|
}
|
|
}
|