/lib/susuka/log/Log.php
PHP | 109 lines | 84 code | 12 blank | 13 comment | 17 complexity | 824254c1b95d82d7ac4d38c4baba213b MD5 | raw file
- <?php
- namespace susuka\log;
- if(!defined('SU_LOG_PATH')) define('SU_LOG_PATH', SU_APP_PATH.'/log');
- /**
- *
- * @todo I'm not sure about this yet... logging should be simple and efficient
- *
- * The general idea is something like:
- * if(SOME_CONSTANT) doTheLogging
- *
- * Where dotheLogging could be:
- * - \suGlobalClass::w(...) <-- This is what we use
- * - \suGlobalLogW(...) <-- Clean, but we cant use class magic (more code in autoload)
- * - \suGetLogInstance()->w(...) <-- Each log is an instance, more overhead when logging is enabled but ignored by logger (due to threshold)
- * and so on...
- */
- class Log {
- protected static $levelMap = array(
- SU_LOG_DEBUG => 'DEBUG',
- SU_LOG_NOTICE => 'NOTICE',
- SU_LOG_WARNING => 'WARNING',
- SU_LOG_ERROR => 'ERROR',
- );
- private static $instances = array();
- private $file;
- public static function d($format) {
- self::_write(SU_LOG_DEBUG, func_get_args());
- }
-
- public static function n($format) {
- self::_write(SU_LOG_NOTICE, func_get_args());
- }
-
- public static function w($format) {
- self::_write(SU_LOG_WARNING, func_get_args());
- }
-
- public static function e($format) {
- self::_write(SU_LOG_ERROR, func_get_args());
- }
-
- public static function format($level, $format) {
- self::_write($level, func_get_args(), 1);
- }
-
- public function __construct($file = null, $threshold = null) {
- if($file === null) {
- $file = defined('SU_LOGFILE') ? SU_LOGFILE : SU_LOG_PATH.'/app.log';
- }
- $this->file = $file;
- $this->threshold = $threshold === null ? SU_LOG : $threshold;
- }
-
- public function write($level, $message) {
- $cat = isset(self::$levelMap[$level]) ? self::$levelMap[$level] : 'UNKNOWN';
- $cat = str_pad($cat, 10, ' ', STR_PAD_LEFT);
- $src = SU_LOG >= SU_LOG_DEBUG ? $this->getSource() : 'UNKNOWN';
- $addr = $_SERVER['REMOTE_ADDR'];
- $msg = sprintf('%s %s %s %s: %s'.PHP_EOL, date(DATE_ATOM), $cat, $addr, $src, $message);
- file_put_contents($this->file, $msg, FILE_APPEND | LOCK_EX);
- }
-
- protected function getSource() {
- $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
- for($i = 0; $i < count($bt); $i++) {
- $b = $bt[$i];
- if(!isset($b['class']) || $b['class'] !== __CLASS__) {
- if(isset($b['class']) && isset($b['function']))
- return $b['class'].'::'.$b['function'];
- else if(isset($b['file']) && isset($b['line']))
- return basename($b['file']).':'.$b['line'];
- return str_replace("\n", " ", print_r($b, true));
- }
- }
- return 'UNKNOWN';
- }
-
- protected static function _write($level, $args, $offset = 0, $instance = null) {
- if($level <= SU_LOG) {
- if($instance === null) {
- $class = get_called_class();
- if(!isset(self::$instances[$class])) {
- self::$instances[$class] = new $class;
- }
- $instance = self::$instances[$class];
- }
- if($level <= $instance->threshold) {
- $args = array_slice($args, $offset);
- $format = array_shift($args);
- foreach($args as &$arg) {
- if(is_array($arg)) {
- $arg = print_r($arg, true);
- $arg = substr($arg, 6); // Remove Array
- $arg = str_replace(' ', '', $arg);
- } else if(is_bool($arg)) {
- $arg = $arg ? 'true' : 'false';
- }
- $arg = str_replace(PHP_EOL, ' ', $arg);
- }
- $message = vsprintf($format, $args);
- $instance->write($level, $message);
- }
- }
- }
- }