diff --git a/library/think/log/driver/Browser.php b/library/think/log/driver/Browser.php new file mode 100644 index 00000000..66106846 --- /dev/null +++ b/library/think/log/driver/Browser.php @@ -0,0 +1,151 @@ + ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'], + ]; + + // 实例化并传入参数 + public function __construct($config = []) + { + if (is_array($config)) { + $this->config = array_merge($this->config, $config); + } + } + + /** + * 日志写入接口 + * @access public + * @param array $log 日志信息 + * @return bool + */ + public function save(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; + $reqs = number_format(1 / number_format($runtime, 8), 2); + $runtime = number_format($runtime, 6); + $mem = number_format((memory_get_usage() - START_MEM) / 1024, 2); + + // 页面Trace信息 + $base = [ + '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], + '运行时间' => "{$runtime}s [ 吞吐率:{$reqs}req/s ] 内存消耗:{$mem}kb 文件加载:" . count(get_included_files()), + '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ', + '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes', + '配置加载' => count(Config::get()), + ]; + + if (session_id()) { + $base['会话信息'] = 'SESSION_ID=' . session_id(); + } + + $info = Debug::getFile(true); + + // 获取调试日志 + $debug = []; + foreach ($log as $type => $val) { + foreach ($val as $msg) { + $debug[$type][] = $msg; + } + } + + // 页面Trace信息 + $trace = []; + foreach ($this->config['trace_tabs'] as $name => $title) { + $name = strtolower($name); + switch ($name) { + case 'base': // 基本信息 + $trace[$title] = $base; + break; + case 'file': // 文件信息 + $trace[$title] = $info; + break; + default: // 调试信息 + if (strpos($name, '|')) { + // 多组信息 + $names = explode('|', $name); + $result = []; + foreach ($names as $name) { + $result = array_merge($result, isset($debug[$name]) ? $debug[$name] : []); + } + $trace[$title] = $result; + } else { + $trace[$title] = isset($debug[$name]) ? $debug[$name] : ''; + } + } + } + + //输出到控制台 + $lines = ''; + foreach ($trace as $type => $msg) { + $lines .= $this->output($type, $msg); + } + $js = << +{$lines} + +JS; + echo $js; + + return true; + } + + public function output($type, $msg){ + $type = strtolower($type); + $trace_tabs = array_values($this->config['trace_tabs']); + $line[] = ($type == $trace_tabs[0] || '调试' == $type || '错误'== $type)? + "console.group('{$type}');" + : + "console.groupCollapsed('{$type}');"; + foreach ($msg as $key => $m) { + switch ($type) { + case '调试': + //我多么希望进来的是原数据格式而不是字符串 + if(substr($m, 0, 5) == 'array'){ + eval("\$o = $m;"); + $line[] = "console.log(".json_encode($o).");"; + }else{ + $msg = addslashes($m); + $msg = str_replace(PHP_EOL, '\n', $msg); + $line[] = "console.log('$msg');"; + } + break; + case '错误': + $msg = str_replace(PHP_EOL, '\n', $m); + $style = 'color:#F4006B;font-size:14px;'; + $line[] = "console.error(\"%c{$msg}\", \"{$style}\");"; + // $line[] = "console.error(".json_encode(debug_backtrace()).");"; + break; + case 'sql': + $msg = str_replace(PHP_EOL, '\n', $m); + $style = "color:#009bb4;"; + $line[] = "console.log(\"%c{$msg}\", \"{$style}\");"; + break; + default: + $m = is_string($key)? $key.' '.$m: $key+1 .' '.$m; + $msg = str_replace(PHP_EOL, '\n', $m); + $line[] = "console.log(\"{$msg}\");"; + break; + } + } + $line[]= "console.groupEnd();"; + return implode(PHP_EOL, $line); + } + +}