diff --git a/src/Pluf/Log.php b/src/Pluf/Log.php new file mode 100644 index 0000000..9ace63f --- /dev/null +++ b/src/Pluf/Log.php @@ -0,0 +1,272 @@ + '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; +} \ No newline at end of file diff --git a/src/Pluf/Log/File.php b/src/Pluf/Log/File.php new file mode 100644 index 0000000..ad2b035 --- /dev/null +++ b/src/Pluf/Log/File.php @@ -0,0 +1,61 @@ +Pluf_Log class. + * + * The only required static method of a log writer is + * write, which takes the stack to write as parameter. + * + * The only configuration variable of the file writer is the path to + * the log file 'pluf_log_file'. By default it creates a + * pluf.log in the configured tmp folder. + * + */ +class Pluf_Log_File +{ + /** + * Flush the stack to the disk. + * + * @param $stack Array + */ + public static function write($stack) + { + $file = Pluf::f('pluf_log_file', + Pluf::f('tmp_folder', '/tmp').'/pluf.log'); + $out = array(); + foreach ($stack as $elt) { + $out[] = date(DATE_ISO8601, (int) $elt[0]).' '. + Pluf_Log::$reverse[$elt[1]].': '. + (string) $elt[2]; + } + $fp = fopen($file, 'a'); + flock($fp, LOCK_EX); // Blocking call. + fputs($fp, implode(PHP_EOL, $out).PHP_EOL); + fclose($fp) ; // release the lock + } +} diff --git a/src/Pluf/Log/Remote.php b/src/Pluf/Log/Remote.php new file mode 100644 index 0000000..3deaaca --- /dev/null +++ b/src/Pluf/Log/Remote.php @@ -0,0 +1,64 @@ +$val) { + $out .= $key.': '.$val."\r\n"; + } + $out.= 'Connection: Close'."\r\n\r\n"; + $out.= $payload; + $fp = fsockopen(Pluf::f('log_remote_server', 'localhost'), + Pluf::f('log_remote_port', 8000), + $errno, $errstr, 5); + fwrite($fp, $out); + fclose($fp); + } +} diff --git a/src/Pluf/Tests/Log/TestLog.php b/src/Pluf/Tests/Log/TestLog.php new file mode 100644 index 0000000..d02229c --- /dev/null +++ b/src/Pluf/Tests/Log/TestLog.php @@ -0,0 +1,91 @@ +logfile = Pluf::f('pluf_log_file', + Pluf::f('tmp_folder', '/tmp').'/pluf.log'); + @unlink($this->logfile); + } + + function tearDown() + { + @unlink($this->logfile); + } + + function testSimple() + { + $GLOBALS['_PX_config']['log_delayed'] = true; + Pluf_Log::log('hello'); + $this->assertEqual(count(Pluf_Log::$stack), 1); + $GLOBALS['_PX_config']['log_delayed'] = false; + Pluf_Log::log('hello'); + $this->assertEqual(count(Pluf_Log::$stack), 0); + $this->assertEqual(2, count(file($this->logfile))); + } + + function testAssertLog() + { + Pluf_Log::activeAssert(); + $GLOBALS['_PX_config']['log_delayed'] = true; + assert('Pluf_Log::alog("hello")'); + $this->assertEqual(count(Pluf_Log::$stack), 1); + $GLOBALS['_PX_config']['log_delayed'] = false; + assert('Pluf_Log::alog("hello")'); + $this->assertEqual(count(Pluf_Log::$stack), 0); + $this->assertEqual(2, count(file($this->logfile))); + + } + + /** + function testPerformance() + { + $start = microtime(true); + $GLOBALS['_PX_config']['log_delayed'] = false; + for ($i=0;$i<100;$i++) { + Pluf_Log::log('hello'.$i); + } + $end = microtime(true); + print "File: ".($end-$start)."s\n"; + $start = microtime(true); + $GLOBALS['_PX_config']['log_delayed'] = true; + for ($i=0;$i<100;$i++) { + Pluf_Log::log('hello'.$i); + } + Pluf_Log::flush(); + $end = microtime(true); + print "File delayed: ".($end-$start)."s\n"; + } + **/ +} \ No newline at end of file diff --git a/src/Pluf/Tests/Log/TestRemote.php b/src/Pluf/Tests/Log/TestRemote.php new file mode 100644 index 0000000..b34fe90 --- /dev/null +++ b/src/Pluf/Tests/Log/TestRemote.php @@ -0,0 +1,86 @@ +assertEqual(count(Pluf_Log::$stack), 1); + $GLOBALS['_PX_config']['log_delayed'] = false; + Pluf_Log::log('hello'); + $this->assertEqual(count(Pluf_Log::$stack), 0); + } + + function testAssertLog() + { + Pluf_Log::activeAssert(); + $GLOBALS['_PX_config']['log_delayed'] = true; + assert('Pluf_Log::alog("hello")'); + $this->assertEqual(count(Pluf_Log::$stack), 1); + $GLOBALS['_PX_config']['log_delayed'] = false; + assert('Pluf_Log::alog("hello")'); + $this->assertEqual(count(Pluf_Log::$stack), 0); + } + + /** + function testPerformance() + { + $start = microtime(true); + $GLOBALS['_PX_config']['log_delayed'] = false; + for ($i=0;$i<100;$i++) { + Pluf_Log::log('hello'.$i); + } + $end = microtime(true); + print "Remote: ".($end-$start)."s\n"; + $start = microtime(true); + $GLOBALS['_PX_config']['log_delayed'] = true; + for ($i=0;$i<100;$i++) { + Pluf_Log::log('hello'.$i); + } + Pluf_Log::flush(); + $end = microtime(true); + print "Remote delayed: ".($end-$start)."s\n"; + } + **/ +} \ No newline at end of file