3.6. 调试系统

一个程序要能写,更要能调试,不然写出来的程序自己都不知道该怎么检查。bzfshop 从设计上就考虑了程序调试的问题,直接在程序框架里面集成了调试功能。你在开发的过程中就可以随时看到需要的调试信息,一旦发生任何错误立马就能看出来。开启 bzfshop 的调试功能很容易,首先把 env.cfg 里面的环境切换成 dev-linux 或者 dev-win (根据你自己的开发系统决定),然后 … 没然后了,调试功能已经开启了,你打开商城看看?(注意:common-dev-win.cfg 里面有自己的数据库配置,请确保里面的数据库配置是正确的)

common-dev-win.cfg里面开启调试功能. 

## 开启调试
DEBUG=3

## 使用我们自己的调试框架
USERDEBUG=1

既然调试功能打开了,下面来看看有哪些调试的方法。

3.6.1. Web日志

当你开启了调试功能之后,打开网站应该能在每个页面的最下方看到 Web日志 输出。这是 bzfshop 程序输出的各种 Log 信息直接在 Web 页面上就显示出来了。从这些日志你也能清楚的看到程序做了那些操作,以及程序的调用流程。

图 3.5. Web页面日志显示

Web页面日志显示

Web日志会是你使用最多的调试方式,大多数时候你直接看页面的日志显示就能判断出问题在哪里了。

3.6.2. 日志文件

普通服务器

Web日志只能在页面上显示,某些时候其实是不存在Web页面的,这个时候你就没法看到Web日志了(比如用户登陆,你做一个 POST ,成功则跳转到用户信息,失败则跳转到登陆页面,由于都是做了跳转,你是没有 Web 页面可以显示 POST 本身的操作)。如果没有 Web页面 可以看,那我们就去看真实的 Log 文件好了。

bzfshop 系统设计有良好的日志机制,很多关键的操作都是有日志记录的(比如用户付款记录),如果你发现有问题可以随时查看这些日志。日志文件保存在 protected/Runtime/Log 目录下,比如 Shop 系统的日志就是类似文件 2013-12-11.shop.debug.log 。打开日志文件,你就能看到 Web 日志一样的内容。

新浪SAE平台

由于新浪SAE平台不允许本地写文件,所以我们也就没法把 log 打印到文件里面了。bzfshop 针对 SAE 平台采用了 sae_debug 实现日志输出(懂 SAE 的人就知道这个是什么)。所以如果你要查看日志需要到 SAE 的管理后台 "应用调优" → "日志中心" → "搜索" 选择 debug ,然后你就能看到 bzfshop 所有的日志输出了。

百度BAE3平台

根据 BAE3 的文档,我们把日志输出在 /home/bae/log 目录下,你可以通过 BAE3 的管理后台查看所有日志记录,如下图:

图 3.6. BAE3平台日志查看

BAE3平台日志查看

3.6.3. Whoops调试

bzfshop 集成了 Whoops 开源库用于调试严重错误。有时候,你的程序写了一个严重的错误(比如 PHP 语法写错了,或者发生了严重的 Exception),这种时候可能连日志系统本身都已经不能正常工作了,所以你压根就没日志可以看,这种情况下该如何调试呢?

下面做我们做一个简单的测试,打开 Theme/Shop/shop/Code/Controller/Shop/Index.php 在里面的 get() 方法处随便乱写一些东西(语法错误)。如下所示:

    public function get($f3)
    {
        global $smarty;

        read_fucking_source_code   // 这里乱打一些东西,制造一个语法错误,相当于你不小心打错了

        // 生成 smarty 的缓存 id
        $smartyCacheId = 'Shop|Index';

        // 开启并设置 smarty 缓存时间
        enableSmartyCache(true, bzf_get_option_value('smarty_cache_time_shop_index'));

        if ($smarty->isCached('shop_index.tpl', $smartyCacheId)) {
            goto out_display;
        }

接下来你再访问商城首页,这个时候你会看到一个调试页面输出,这里面包含了所有你调试所需要用到的信息。通过这些信息你就能很容易的找到错误发生的地方,并且快速的修复错误。Whoops 不止限于语法错误的调试,如果你的程序发生了 Exception Whoops 也一样会给出调试页面,让你可以很容易就定位到 Exception 抛出的地方。

图 3.7. Whoops调试页面

Whoops调试页面

3.6.4. 其它调试

Web页面调试本身就不好操作,基本上打印日志、查看日志可以说是最有效的方法了。如果你觉得 bzfshop 提供的调试方法还不够,那么你还可以使用你自己喜欢的方法。

我们用过的调试方法还有 ZendDebugger/XDebug 配合 IDE 做单步执行,一行一行的代码走下去,跟踪错误直到我们发现问题为止。这种情况一般用于逻辑错误,即程序能跑过,但是输出的结果就是不对,逻辑错误很难查找,于是考虑单步执行。但是这种单步执行效率真心不高,调试起来效率也很低,还不如打印 Log 来得快,所以我们用得很少,或者说基本不用。

目前我们只用 XDebug 配合 Valgrind 做性能剖析(Performance Profile)。一般在程序开发的晚期,我们会做 Performance Profile ,确定性能的瓶颈在什么地方,然后做相应的优化,我们也用相同的方法来验证缓存带来的性能提升是否有效。具体这些性能调优的方法我们会在 bzfshop设计文档 中详细写,这里就不再展开了。

3.6.5. 调试总结

bzfshop 系统提供 3 种调试的方法:

  • Web 页面日志
  • 日志文件
  • Whoops 调试

最简单、最常用的就是 Web 页面日志,你在程序里面打印 debug 日志,Web 页面直接就显示了出来,方便你随时查看。如果 Web 页面不存在,那你就去日志文件中查看日志。如果系统发生严重错误(系统崩溃了)Whoops 调试系统会帮助你迅速找到错误所在。