改进trace

This commit is contained in:
yunwuxin
2016-06-29 17:35:37 +08:00
parent d9a9599043
commit f01b2cd8b7
13 changed files with 163 additions and 129 deletions

View File

@@ -8,9 +8,14 @@
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
function microtime_float()
{
list ($usec, $sec) = explode(" ", microtime());
return (( float )$usec + ( float )$sec);
}
define('THINK_VERSION', '5.0.0 RC3'); define('THINK_VERSION', '5.0.0 RC3');
define('START_TIME', microtime(true)); define('START_TIME', microtime_float());
define('START_MEM', memory_get_usage()); define('START_MEM', memory_get_usage());
define('EXT', '.php'); define('EXT', '.php');
define('DS', DIRECTORY_SEPARATOR); define('DS', DIRECTORY_SEPARATOR);

View File

@@ -146,6 +146,13 @@ return [
'path' => LOG_PATH, 'path' => LOG_PATH,
], ],
// +----------------------------------------------------------------------
// | Trace设置
// +----------------------------------------------------------------------
'trace' => [
'type' => 'Html'
],
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | 缓存设置 // | 缓存设置
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------

View File

@@ -12,6 +12,7 @@
namespace think; namespace think;
use think\Config; use think\Config;
use think\debug\Trace;
use think\Exception; use think\Exception;
use think\exception\HttpException; use think\exception\HttpException;
use think\exception\HttpResponseException; use think\exception\HttpResponseException;
@@ -70,7 +71,7 @@ class App
* 执行应用程序 * 执行应用程序
* @access public * @access public
* @param Request $request Request对象 * @param Request $request Request对象
* @return mixed * @return Response
* @throws Exception * @throws Exception
*/ */
public static function run(Request $request = null) public static function run(Request $request = null)
@@ -136,22 +137,27 @@ class App
$data = $exception->getResponse(); $data = $exception->getResponse();
} }
// 监听app_end
Hook::listen('app_end', $data);
// 清空类的实例化 // 清空类的实例化
Loader::clearInstance(); Loader::clearInstance();
// 输出数据到客户端 // 输出数据到客户端
if ($data instanceof Response) { if ($data instanceof Response) {
return $data; $response = $data;
} elseif (!is_null($data)) { } elseif (!is_null($data)) {
// 默认自动识别响应输出类型 // 默认自动识别响应输出类型
$isAjax = $request->isAjax(); $isAjax = $request->isAjax();
$type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); $type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');
return Response::create($data, $type); $response = Response::create($data, $type);
} else { } else {
return Response::create(); $response = Response::create();
} }
self::$debug && Trace::inject($response);
// 监听app_end
Hook::listen('app_end', $response);
return $response;
} }
/** /**

View File

@@ -43,9 +43,8 @@ class Hook
/** /**
* 批量导入插件 * 批量导入插件
* @param array $data 插件信息 * @param array $tags 插件信息
* @param boolean $recursive 是否递归合并 * @param boolean $recursive 是否递归合并
* @return void
*/ */
public static function import($tags, $recursive = true) public static function import($tags, $recursive = true)
{ {

View File

@@ -11,8 +11,17 @@
namespace think; namespace think;
use think\App; /**
* Class Log
* @package think
*
* @method void log($msg) static
* @method void error($msg) static
* @method void info($msg) static
* @method void sql($msg) static
* @method void notice($msg) static
* @method void alert($msg) static
*/
class Log class Log
{ {
const LOG = 'log'; const LOG = 'log';
@@ -30,16 +39,15 @@ class Log
protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert']; protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert'];
// 日志写入驱动 // 日志写入驱动
protected static $driver; protected static $driver;
// 通知发送驱动
protected static $alarm;
// 当前日志授权key // 当前日志授权key
protected static $key; protected static $key;
/** /**
* 日志初始化 * 日志初始化
* @return void * @param array $config
*/ */
public static function init($config = []) public static function init($config = [])
{ {
$type = isset($config['type']) ? $config['type'] : 'File'; $type = isset($config['type']) ? $config['type'] : 'File';
$class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type); $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type);
@@ -49,21 +57,7 @@ class Log
// 记录初始化信息 // 记录初始化信息
App::$debug && Log::record('[ LOG ] INIT ' . $type . ': ' . var_export($config, true), 'info'); App::$debug && Log::record('[ LOG ] INIT ' . $type . ': ' . var_export($config, true), 'info');
} }
/**
* 通知初始化
* @return void
*/
public static function alarm($config = [])
{
$type = isset($config['type']) ? $config['type'] : 'Email';
$class = false !== strpos($type, '\\') ? $type : '\\think\\log\\alarm\\' . ucwords($type);
unset($config['type']);
self::$alarm = new $class($config['alarm']);
// 记录初始化信息
App::$debug && Log::record('[ CACHE ] ALARM ' . $type . ': ' . var_export($config, true), 'info');
}
/** /**
* 获取日志信息 * 获取日志信息
* @param string $type 信息类型 * @param string $type 信息类型
@@ -164,19 +158,11 @@ class Log
return self::$driver->save($log); return self::$driver->save($log);
} }
/**
* 发送预警通知
* @param mixed $msg 调试信息
* @return void
*/
public static function send($msg)
{
self::$alarm && self::$alarm->send($msg);
}
/** /**
* 静态调用 * 静态调用
* @return void * @param $method
* @param $args
* @return mixed
*/ */
public static function __callStatic($method, $args) public static function __callStatic($method, $args)
{ {

View File

@@ -93,9 +93,6 @@ class Response
// 处理输出数据 // 处理输出数据
$data = $this->getContent(); $data = $this->getContent();
// 监听response_data
Hook::listen('response_data', $data, $this);
if (!headers_sent() && !empty($this->header)) { if (!headers_sent() && !empty($this->header)) {
// 发送状态码 // 发送状态码
http_response_code($this->code); http_response_code($this->code);
@@ -165,6 +162,26 @@ class Response
return $this; return $this;
} }
/**
* 设置页面输出内容
* @param $content
* @return $this
*/
public function content($content)
{
if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
$content,
'__toString',
])
) {
throw new \InvalidArgumentException(sprintf('variable type error %s', gettype($content)));
}
$this->content = (string)$content;
return $this;
}
/** /**
* 发送HTTP状态 * 发送HTTP状态
* @param integer $code 状态码 * @param integer $code 状态码
@@ -228,10 +245,30 @@ class Response
*/ */
public function contentType($contentType, $charset = 'utf-8') public function contentType($contentType, $charset = 'utf-8')
{ {
$this->contentType = $contentType;
$this->charset = $charset;
$this->header['Content-Type'] = $contentType . '; charset=' . $charset; $this->header['Content-Type'] = $contentType . '; charset=' . $charset;
return $this; return $this;
} }
/**
* 获取页面输出类型
* @return string
*/
public function getContentType()
{
return $this->contentType;
}
/**
* 获取页面输出字符集
*/
public function getCharset()
{
return $this->charset;
}
/** /**
* 获取头部信息 * 获取头部信息
* @param string $name 头部名称 * @param string $name 头部名称
@@ -257,17 +294,20 @@ class Response
*/ */
public function getContent() public function getContent()
{ {
$content = $this->output($this->data); if ($this->content == null) {
$content = $this->output($this->data);
if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
$content, $content,
'__toString', '__toString',
]) ])
) { ) {
throw new \InvalidArgumentException(sprintf('variable type error %s', gettype($content))); throw new \InvalidArgumentException(sprintf('variable type error %s', gettype($content)));
}
$this->content = (string)$content;
} }
return $this->content;
return (string) $content;
} }
/** /**

View File

@@ -0,0 +1,47 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
namespace think\debug;
use think\Config;
use think\Log;
use think\Request;
use think\Response;
class Trace
{
public static function inject(Response $response)
{
$config = Config::get('trace');
$type = isset($config['type']) ? $config['type'] : 'Html';
if ($type !== false && !Request::instance()->isAjax() && $response->getContentType() == 'text/html') {
$class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\trace\\' . ucwords($type);
unset($config['type']);
$trace = new $class($config);
$output = $trace->output(Log::getLog());
$content = $response->getContent();
$pos = strripos($content, '</body>');
if (false !== $pos) {
$content = substr($content, 0, $pos) . $output . substr($content, $pos);
} else {
$content = $content . $output;
}
$response->content($content);
}
}
}

View File

@@ -9,7 +9,7 @@
// | Author: yangweijie <yangweijiester@gmail.com> // | Author: yangweijie <yangweijiester@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace think\log\driver; namespace think\debug\trace;
use think\Cache; use think\Cache;
use think\Config; use think\Config;
@@ -40,16 +40,11 @@ class Browser
* @param array $log 日志信息 * @param array $log 日志信息
* @return bool * @return bool
*/ */
public function save(array $log = []) public function output(array $log = [])
{ {
if (IS_CLI || IS_API || Request::instance()->isAjax() || (defined('RESPONSE_TYPE') && !in_array(RESPONSE_TYPE, ['html', 'view']))) {
// ajax cli api方式下不输出
return false;
}
// 获取基本信息 // 获取基本信息
$runtime = microtime(true) - START_TIME; $runtime = microtime_float() - START_TIME;
$reqs = number_format(1 / number_format($runtime, 8), 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$mem = number_format((memory_get_usage() - START_MEM) / 1024, 2); $mem = number_format((memory_get_usage() - START_MEM) / 1024, 2);
// 页面Trace信息 // 页面Trace信息
@@ -96,19 +91,18 @@ class Browser
//输出到控制台 //输出到控制台
$lines = ''; $lines = '';
foreach ($trace as $type => $msg) { foreach ($trace as $type => $msg) {
$lines .= $this->output($type, $msg); $lines .= $this->console($type, $msg);
} }
$js = <<<JS $js = <<<JS
<script> <script type='text/javascript'>
{$lines} {$lines}
</script> </script>
JS; JS;
echo $js; return $js;
return true;
} }
public function output($type, $msg) protected function console($type, $msg)
{ {
$type = strtolower($type); $type = strtolower($type);
$trace_tabs = array_values($this->config['trace_tabs']); $trace_tabs = array_values($this->config['trace_tabs']);

View File

@@ -9,7 +9,7 @@
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
namespace think\log\driver; namespace think\debug\trace;
use think\Cache; use think\Cache;
use think\Config; use think\Config;
@@ -20,7 +20,7 @@ use think\Request;
/** /**
* 页面Trace调试 * 页面Trace调试
*/ */
class Trace class Html
{ {
protected $config = [ protected $config = [
'trace_file' => '', 'trace_file' => '',
@@ -40,17 +40,12 @@ class Trace
* @param array $log 日志信息 * @param array $log 日志信息
* @return bool * @return bool
*/ */
public function save(array $log = []) public function output(array $log = [])
{ {
if (IS_CLI || IS_API || Request::instance()->isAjax() || (defined('RESPONSE_TYPE') && !in_array(RESPONSE_TYPE, ['html', 'view']))) {
// ajax cli api方式下不输出
return false;
}
// 获取基本信息 // 获取基本信息
$runtime = microtime(true) - START_TIME; $runtime = microtime_float() - START_TIME;
$reqs = number_format(1 / number_format($runtime, 8), 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$mem = number_format((memory_get_usage() - START_MEM) / 1024, 2); $mem = number_format((memory_get_usage() - START_MEM) / 1024, 2);
// 页面Trace信息 // 页面Trace信息
@@ -96,8 +91,7 @@ class Trace
// 调用Trace页面模板 // 调用Trace页面模板
ob_start(); ob_start();
include $this->config['trace_file']; include $this->config['trace_file'];
echo ob_get_clean(); return ob_get_clean();
return true;
} }
} }

View File

@@ -1,41 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace think\log\alarm;
/**
* 邮件通知驱动
*/
class Email
{
protected $config = [
'address' => '',
];
// 实例化并传入参数
public function __construct($config = [])
{
$this->config = array_merge($this->config, $config);
}
/**
* 通知发送接口
* @access public
* @param string $msg 日志信息
* @return bool
*/
public function send($msg = '')
{
return error_log($msg, 1, $this->config['address']);
}
}

View File

@@ -54,9 +54,8 @@ class File
} else { } else {
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']); $current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
} }
$runtime = microtime(true) - START_TIME; $runtime = microtime_float() - START_TIME;
$reqs = number_format(1 / number_format($runtime, 8), 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]"; $time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]";
$memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2); $memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2);
$memory_str = " [内存消耗:{$memory_use}kb]"; $memory_str = " [内存消耗:{$memory_use}kb]";

View File

@@ -33,9 +33,8 @@ class Sae
} else { } else {
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']); $current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
} }
$runtime = microtime(true) - START_TIME; $runtime = microtime_float() - START_TIME;
$reqs = number_format(1 / number_format($runtime, 8), 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]"; $time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]";
$memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2); $memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2);
$memory_str = " [内存消耗:{$memory_use}kb]"; $memory_str = " [内存消耗:{$memory_use}kb]";

View File

@@ -65,9 +65,8 @@ class Socket
if (!$this->check()) { if (!$this->check()) {
return false; return false;
} }
$runtime = microtime(true) - START_TIME; $runtime = microtime_float() - START_TIME;
$reqs = number_format(1 / number_format($runtime, 8), 2); $reqs = number_format(1 / number_format($runtime, 8), 2);
$runtime = number_format($runtime, 6);
$time_str = " [运行时间:{$runtime}s][吞吐率:{$reqs}req/s]"; $time_str = " [运行时间:{$runtime}s][吞吐率:{$reqs}req/s]";
$memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2); $memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2);
$memory_str = " [内存消耗:{$memory_use}kb]"; $memory_str = " [内存消耗:{$memory_use}kb]";