Quellcode durchsuchen

Update: Add Chrome logger

zhujinhui vor 2 Jahren
Ursprung
Commit
eed480dc86

+ 1 - 1
composer.json

@@ -11,7 +11,7 @@
     ],
     "minimum-stability": "dev",
     "require": {
-        "php": ">=5.3.0",
+        "php": ">=5.4",
         "ext-gd" : ">=2.1.0"
     }
 }

+ 1 - 1
demo/private/plugins/loger.php

@@ -1,7 +1,7 @@
 <?php
 namespace plugins;
 
-class loger implements \Qii\Loger\Writer
+class loger implements \Qii\Logger\Writer
 {
 	public $logerPath = 'tmp';
 	public $fileName = 'loger.log';

+ 1 - 1
src/Conf/namespace.php

@@ -39,7 +39,7 @@ return [
         ['Qii\Exceptions', Qii_DIR . DS . 'Exceptions'],
         ['Qii\Language', Qii_DIR . DS . 'Language'],
         ['Qii\Library', Qii_DIR . DS . 'Library'],
-        ['Qii\Loger', Qii_DIR . DS . 'Loger'],
+        ['Qii\Logger', Qii_DIR . DS . 'Logger'],
         ['Qii\Plugin', Qii_DIR . DS . 'Plugin'],
         ['Qii\Request', Qii_DIR . DS . 'Request'],
         ['Qii\Response', Qii_DIR . DS . 'Response'],

+ 428 - 0
src/Logger/Chromelog.php

@@ -0,0 +1,428 @@
+<?php
+namespace Qii\Logger;
+/**
+ * 使用方法:
+ * \Qii\Logger\Chromelog::log("text", "这是log内容");
+ */
+class Chromelog {
+    /**
+     * @var string
+     */
+    const VERSION = '4.1.0';
+
+    /**
+     * @var string
+     */
+    const HEADER_NAME = 'X-ChromeLogger-Data';
+
+    /**
+     * @var string
+     */
+    const BACKTRACE_LEVEL = 'backtrace_level';
+
+    /**
+     * @var string
+     */
+    const LOG = 'log';
+
+    /**
+     * @var string
+     */
+    const WARN = 'warn';
+
+    /**
+     * @var string
+     */
+    const ERROR = 'error';
+
+    /**
+     * @var string
+     */
+    const GROUP = 'group';
+
+    /**
+     * @var string
+     */
+    const INFO = 'info';
+
+    /**
+     * @var string
+     */
+    const GROUP_END = 'groupEnd';
+
+    /**
+     * @var string
+     */
+    const GROUP_COLLAPSED = 'groupCollapsed';
+
+    /**
+     * @var string
+     */
+    const TABLE = 'table';
+
+    /**
+     * @var string
+     */
+    protected $_php_version;
+
+    /**
+     * @var int
+     */
+    protected $_timestamp;
+
+    /**
+     * @var array
+     */
+    protected $_json = array(
+        'version' => self::VERSION,
+        'columns' => array('log', 'backtrace', 'type'),
+        'rows' => array()
+    );
+
+    /**
+     * @var array
+     */
+    protected $_backtraces = array();
+
+    /**
+     * @var bool
+     */
+    protected $_error_triggered = false;
+
+    /**
+     * @var array
+     */
+    protected $_settings = array(
+        self::BACKTRACE_LEVEL => 1
+    );
+
+    /**
+     * @var ChromePhp
+     */
+    protected static $_instance;
+
+    /**
+     * Prevent recursion when working with objects referring to each other
+     *
+     * @var array
+     */
+    protected $_processed = array();
+
+    /**
+     * constructor
+     */
+    private function __construct()
+    {
+        $this->_php_version = phpversion();
+        $this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time();
+        $this->_json['request_uri'] = $_SERVER['REQUEST_URI'];
+    }
+
+    /**
+     * gets instance of this class
+     *
+     * @return ChromePhp
+     */
+    public static function getInstance()
+    {
+        if (self::$_instance === null) {
+            self::$_instance = new self();
+        }
+        return self::$_instance;
+    }
+
+    /**
+     * logs a variable to the console
+     *
+     * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
+     * @return void
+     */
+    public static function log()
+    {
+        $args = func_get_args();
+        return self::_log('', $args);
+    }
+
+    /**
+     * logs a warning to the console
+     *
+     * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
+     * @return void
+     */
+    public static function warn()
+    {
+        $args = func_get_args();
+        return self::_log(self::WARN, $args);
+    }
+
+    /**
+     * logs an error to the console
+     *
+     * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
+     * @return void
+     */
+    public static function error()
+    {
+        $args = func_get_args();
+        return self::_log(self::ERROR, $args);
+    }
+
+    /**
+     * sends a group log
+     *
+     * @param string value
+     */
+    public static function group()
+    {
+        $args = func_get_args();
+        return self::_log(self::GROUP, $args);
+    }
+
+    /**
+     * sends an info log
+     *
+     * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
+     * @return void
+     */
+    public static function info()
+    {
+        $args = func_get_args();
+        return self::_log(self::INFO, $args);
+    }
+
+    /**
+     * sends a collapsed group log
+     *
+     * @param string value
+     */
+    public static function groupCollapsed()
+    {
+        $args = func_get_args();
+        return self::_log(self::GROUP_COLLAPSED, $args);
+    }
+
+    /**
+     * ends a group log
+     *
+     * @param string value
+     */
+    public static function groupEnd()
+    {
+        $args = func_get_args();
+        return self::_log(self::GROUP_END, $args);
+    }
+
+    /**
+     * sends a table log
+     *
+     * @param string value
+     */
+    public static function table()
+    {
+        $args = func_get_args();
+        return self::_log(self::TABLE, $args);
+    }
+
+    /**
+     * internal logging call
+     *
+     * @param string $type
+     * @return void
+     */
+    protected static function _log($type, array $args)
+    {
+        // nothing passed in, don't do anything
+        if (count($args) == 0 && $type != self::GROUP_END) {
+            return;
+        }
+
+        $logger = self::getInstance();
+
+        $logger->_processed = array();
+
+        $logs = array();
+        foreach ($args as $arg) {
+            $logs[] = $logger->_convert($arg);
+        }
+
+        $backtrace = debug_backtrace(false);
+        $level = $logger->getSetting(self::BACKTRACE_LEVEL);
+
+        $backtrace_message = 'unknown';
+        if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) {
+            $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line'];
+        }
+
+        $logger->_addRow($logs, $backtrace_message, $type);
+    }
+
+    /**
+     * converts an object to a better format for logging
+     *
+     * @param Object
+     * @return array
+     */
+    protected function _convert($object)
+    {
+        // if this isn't an object then just return it
+        if (!is_object($object)) {
+            return $object;
+        }
+
+        //Mark this object as processed so we don't convert it twice and it
+        //Also avoid recursion when objects refer to each other
+        $this->_processed[] = $object;
+
+        $object_as_array = array();
+
+        // first add the class name
+        $object_as_array['___class_name'] = get_class($object);
+
+        // loop through object vars
+        $object_vars = get_object_vars($object);
+        foreach ($object_vars as $key => $value) {
+
+            // same instance as parent object
+            if ($value === $object || in_array($value, $this->_processed, true)) {
+                $value = 'recursion - parent object [' . get_class($value) . ']';
+            }
+            $object_as_array[$key] = $this->_convert($value);
+        }
+
+        $reflection = new ReflectionClass($object);
+
+        // loop through the properties and add those
+        foreach ($reflection->getProperties() as $property) {
+
+            // if one of these properties was already added above then ignore it
+            if (array_key_exists($property->getName(), $object_vars)) {
+                continue;
+            }
+            $type = $this->_getPropertyKey($property);
+
+            if ($this->_php_version >= 5.3) {
+                $property->setAccessible(true);
+            }
+
+            try {
+                $value = $property->getValue($object);
+            } catch (ReflectionException $e) {
+                $value = 'only PHP 5.3 can access private/protected properties';
+            }
+
+            // same instance as parent object
+            if ($value === $object || in_array($value, $this->_processed, true)) {
+                $value = 'recursion - parent object [' . get_class($value) . ']';
+            }
+
+            $object_as_array[$type] = $this->_convert($value);
+        }
+        return $object_as_array;
+    }
+
+    /**
+     * takes a reflection property and returns a nicely formatted key of the property name
+     *
+     * @param ReflectionProperty
+     * @return string
+     */
+    protected function _getPropertyKey(ReflectionProperty $property)
+    {
+        $static = $property->isStatic() ? ' static' : '';
+        if ($property->isPublic()) {
+            return 'public' . $static . ' ' . $property->getName();
+        }
+
+        if ($property->isProtected()) {
+            return 'protected' . $static . ' ' . $property->getName();
+        }
+
+        if ($property->isPrivate()) {
+            return 'private' . $static . ' ' . $property->getName();
+        }
+    }
+
+    /**
+     * adds a value to the data array
+     *
+     * @var mixed
+     * @return void
+     */
+    protected function _addRow(array $logs, $backtrace, $type)
+    {
+        // if this is logged on the same line for example in a loop, set it to null to save space
+        if (in_array($backtrace, $this->_backtraces)) {
+            $backtrace = null;
+        }
+
+        // for group, groupEnd, and groupCollapsed
+        // take out the backtrace since it is not useful
+        if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) {
+            $backtrace = null;
+        }
+
+        if ($backtrace !== null) {
+            $this->_backtraces[] = $backtrace;
+        }
+
+        $row = array($logs, $backtrace, $type);
+
+        $this->_json['rows'][] = $row;
+        $this->_writeHeader($this->_json);
+    }
+
+    protected function _writeHeader($data)
+    {
+        header(self::HEADER_NAME . ': ' . $this->_encode($data));
+    }
+
+    /**
+     * encodes the data to be sent along with the request
+     *
+     * @param array $data
+     * @return string
+     */
+    protected function _encode($data)
+    {
+        return base64_encode(utf8_encode(json_encode($data)));
+    }
+
+    /**
+     * adds a setting
+     *
+     * @param string key
+     * @param mixed value
+     * @return void
+     */
+    public function addSetting($key, $value)
+    {
+        $this->_settings[$key] = $value;
+    }
+
+    /**
+     * add ability to set multiple settings in one call
+     *
+     * @param array $settings
+     * @return void
+     */
+    public function addSettings(array $settings)
+    {
+        foreach ($settings as $key => $value) {
+            $this->addSetting($key, $value);
+        }
+    }
+
+    /**
+     * gets a setting
+     *
+     * @param string key
+     * @return mixed
+     */
+    public function getSetting($key)
+    {
+        if (!isset($this->_settings[$key])) {
+            return null;
+        }
+        return $this->_settings[$key];
+    }
+}

+ 2 - 2
src/Loger/Instance.php → src/Logger/Instance.php

@@ -2,9 +2,9 @@
 /**
  * 注册一个写日志的插件,由项目本身去实现是否写日志,当框架在抛出异常的时候会触发写日志的操作
  */
-namespace Qii\Loger;
+namespace Qii\Logger;
 
-use \Qii\Loger\Writer;
+use \Qii\Logger\Writer;
 class Instance
 {
 	const VERSION = '1.2';

+ 1 - 1
src/Loger/Writer.php → src/Logger/Writer.php

@@ -1,5 +1,5 @@
 <?php
-namespace Qii\Loger;
+namespace Qii\Logger;
 
 interface Writer
 {