<?php␊ |
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */␊ |
/*␊ |
# ***** BEGIN LICENSE BLOCK *****␊ |
# This file is part of Plume Framework, a simple PHP Application Framework.␊ |
# Copyright (C) 2001-2009 Loic d'Anterroches and contributors.␊ |
#␊ |
# Plume Framework is free software; you can redistribute it and/or modify␊ |
# it under the terms of the GNU Lesser General Public License as published by␊ |
# the Free Software Foundation; either version 2.1 of the License, or␊ |
# (at your option) any later version.␊ |
#␊ |
# Plume Framework is distributed in the hope that it will be useful,␊ |
# but WITHOUT ANY WARRANTY; without even the implied warranty of␊ |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the␊ |
# GNU Lesser General Public License for more details.␊ |
#␊ |
# You should have received a copy of the GNU Lesser General Public License␊ |
# along with this program; if not, write to the Free Software␊ |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA␊ |
#␊ |
# ***** END LICENSE BLOCK ***** */␊ |
␊ |
/**␊ |
* High performance logging infrastructure.␊ |
*␊ |
* Logging while keeping a high performance in production is hard, it␊ |
* is even harder if we want to track the point in the code where the␊ |
* log information is generated, for example the file name and line␊ |
* number. PHP offers the assert statement which, used in a not so␊ |
* conventional way can get everything in a very efficient way.␊ |
*␊ |
* Note that the messages do not need to be strings. You can log␊ |
* whatever you want. How the message is then stored in your logs is␊ |
* up to the writer you are using. This can be for example a JSON␊ |
* fragment.␊ |
*␊ |
* The removal of constraints on the log message simplify the log␊ |
* system as you can push into it categories or extra informations.␊ |
*␊ |
* In the log stack, each log message is microtimed together with the␊ |
* log level as integer. You can convert the integer to string at␊ |
* write time.␊ |
*␊ |
*/␊ |
class Pluf_Log␊ |
{␊ |
/**␊ |
* The log stack.␊ |
*␊ |
* A logger function is just pushing the data in the log stack,␊ |
* the writers are then called to write the data later.␊ |
*/␊ |
public static $stack = array();␊ |
␊ |
/**␊ |
* Different log levels.␊ |
*/␊ |
const ALL = 1;␊ |
const DEBUG = 5;␊ |
const INFO = 6;␊ |
const WARN = 7;␊ |
const ERROR = 8;␊ |
const FATAL = 9;␊ |
const OFF = 10;␊ |
␊ |
/**␊ |
* Used to reverse the log level to the string.␊ |
*/␊ |
public static $reverse = array(1 => 'ALL',␊ |
5 => 'DEBUG',␊ |
6 => 'INFO',␊ |
7 => 'WARN',␊ |
8 => 'ERROR',␊ |
9 => 'FATAL');␊ |
␊ |
/**␊ |
* Current log level.␊ |
*␊ |
* By default, set to 6, which is the INFO level.␊ |
*/␊ |
public static $level = 6;␊ |
␊ |
/**␊ |
* Current message in the assert log.␊ |
*/␊ |
public static $assert_mess = null;␊ |
␊ |
/**␊ |
* Current level of the message in the assert log.␊ |
*/␊ |
public static $assert_level = 6;␊ |
␊ |
/**␊ |
* Log the information in the stack.␊ |
*␊ |
* Flush the information if needed.␊ |
*␊ |
* @param $level Level to log␊ |
* @param $message Message to log␊ |
*/␊ |
private static function _log($level, $message)␊ |
{␊ |
␊ |
if (self::$level >= $level and self::$level != 10) {␊ |
self::$stack[] = array(microtime(true), $level, $message);␊ |
if (!Pluf::f('log_delayed', false)) {␊ |
self::flush();␊ |
}␊ |
}␊ |
}␊ |
␊ |
/**␊ |
* Base assert logger.␊ |
*␊ |
* The assert logging is a two step process as one need to go␊ |
* through the assertion callback.␊ |
*␊ |
* @param $level Level to log␊ |
* @param $message Message to log␊ |
* @return bool false␊ |
*/␊ |
private static function _alog($level, $message)␊ |
{␊ |
self::$assert_level = $level;␊ |
self::$assert_mess = $message;␊ |
return false; // This will trigger the assert handler.␊ |
}␊ |
␊ |
/**␊ |
* Log at the ALL level.␊ |
*␊ |
* @param $message Message to log␊ |
*/␊ |
public static function log($message)␊ |
{␊ |
return self::_log(self::ALL, $message);␊ |
}␊ |
␊ |
/**␊ |
* Log at the DEBUG level.␊ |
*␊ |
* @param $message Message to log␊ |
*/␊ |
public static function debug($message)␊ |
{␊ |
self::_log(self::DEBUG, $message);␊ |
}␊ |
␊ |
public static function info($message)␊ |
{␊ |
self::_log(self::INFO, $message);␊ |
}␊ |
␊ |
public static function warn($message)␊ |
{␊ |
self::_log(self::WARN, $message);␊ |
}␊ |
␊ |
public static function error($message)␊ |
{␊ |
self::_log(self::ERROR, $message);␊ |
}␊ |
␊ |
public static function fatal($message)␊ |
{␊ |
self::_log(self::FATAL, $message);␊ |
}␊ |
␊ |
/**␊ |
* Assert log at the ALL level.␊ |
*␊ |
* @param $message Message to log␊ |
*/␊ |
public static function alog($message)␊ |
{␊ |
return self::_alog(self::ALL, $message);␊ |
}␊ |
␊ |
/**␊ |
* Assert log at the DEBUG level.␊ |
*␊ |
* @param $message Message to log␊ |
*/␊ |
public static function adebug($message)␊ |
{␊ |
self::_alog(self::DEBUG, $message);␊ |
}␊ |
␊ |
public static function ainfo($message)␊ |
{␊ |
self::_alog(self::INFO, $message);␊ |
}␊ |
␊ |
public static function awarn($message)␊ |
{␊ |
self::_alog(self::WARN, $message);␊ |
}␊ |
␊ |
public static function aerror($message)␊ |
{␊ |
self::_alog(self::ERROR, $message);␊ |
}␊ |
␊ |
public static function afatal($message)␊ |
{␊ |
self::_alog(self::FATAL, $message);␊ |
}␊ |
␊ |
/**␊ |
* Flush the data to the writer.␊ |
*␊ |
* This reset the stack.␊ |
*/␊ |
public static function flush()␊ |
{␊ |
$writer = Pluf::f('log_handler', 'Pluf_Log_File');␊ |
call_user_func(array($writer, 'write'), self::$stack);␊ |
self::$stack = array();␊ |
}␊ |
␊ |
/**␊ |
* Signal handler to flush the log.␊ |
*␊ |
* The name of the signal and the parameters are not used.␊ |
*␊ |
* @param $signal Name of the signal␊ |
* @param &$params Parameters␊ |
*/␊ |
public static function flushHandler($signal, &$params)␊ |
{␊ |
self::flush();␊ |
}␊ |
␊ |
/**␊ |
* Activation of the low impact logging.␊ |
*␊ |
* When called, it enabled the assertions for debugging.␊ |
*/␊ |
public static function activeAssert()␊ |
{␊ |
assert_options(ASSERT_ACTIVE, 1); ␊ |
assert_options(ASSERT_WARNING, 0);␊ |
assert_options(ASSERT_QUIET_EVAL, 1);␊ |
assert_options(ASSERT_CALLBACK, 'Pluf_Log_assert');␊ |
}␊ |
}␊ |
␊ |
/**␊ |
* Assertion handler.␊ |
*␊ |
* @param $file Name of the file where the assert is called␊ |
* @param $line Line number of the file where the assert is called␊ |
* @param $code Code evaluated by the assert call␊ |
*/␊ |
function Pluf_Log_assert($file, $line, $code)␊ |
{␊ |
if (Pluf_Log::$level >= Pluf_Log::$assert_level and ␊ |
Pluf_Log::$level != 10) {␊ |
Pluf_Log::$stack[] = array(␊ |
microtime(true),␊ |
Pluf_Log::$assert_level,␊ |
Pluf_Log::$assert_mess,␊ |
$file, $line, $code);␊ |
if (!Pluf::f('log_delayed', false)) {␊ |
Pluf_Log::flush();␊ |
}␊ |
␊ |
}␊ |
Pluf_Log::$assert_level = 6;␊ |
Pluf_Log::$assert_mess = null;␊ |
} |