转载自http://www.thinkphp.cn/topic/10846.htmlphp
正在运行的API有bug,不能var_dump进行调试,由于会影响client的调用。这时候用SocketLog最好,SocketLog经过websocket将调试日志打印到浏览器的console中。你还能够用它来分析开源程序,分析SQL性能,结合taint分析程序漏洞。
我将演示如何用SocketLog分析php程序, SocketLog的项目地址:https://github.com/luofei614/SocketLog
#说明
* SocketLog方便API,AJAX的调试,能将日志经过WebSocket输出到Chrome浏览器的console中
* 它能代替ChromePHP、FirePHP等工具,ChromePHP等是经过header通讯,适合AJAX调试,但不适合API调试,并且它们是经过Header通讯,Chrome浏览器对传递Header大小有限制,日志若是多了,Chrome浏览器就没法支持。
* 目录结构:
* chrome 目录是 chrome插件的源代码
* chrome.crx 文件是chrome插件的安装包, 目前插件尚未上架到Chrome App Store, 你们须要手动安装, 浏览器地址栏输入并打开: chrome://extensions/ ,而后将chrome.crx拖入便可安装。
* php 目录是php相关脚本。 SocketLog.server.php 是一个 Websocket服务器, SocketLog.class.php是发送日志的类库,咱们在发送日志的时候,须要载入这个类库而后调用函数slog便可。
* 效果展现: 咱们在浏览网站的时候在浏览器console中就知道程序作了什么,这对于二次开发产品十分有用。 下面效果图在console中打印出浏览discuz程序时,执行了哪些sql语句, 以及执行sql语句的调用栈。程序的warning,notice等错误信息也能够打到console中。
#使用方法
* 首先,请在chrome浏览器上安装好插件。
* 而后,启用Websocket服务, 在命令行中运行 `php php/SocketLog.server.php` , 将会在本地起一个websocket服务 ,监听端口是1229 。 若是想服务后台运行: `nohup php php/SocketLog.server.php > /dev/null &`
* 在本身的程序中发送日志:css
* 用slog函数发送日志, 支持多种日志类型:html
* 经过上面例子能够看出, slog函数支持三个参数:
* 第一个参数是日志内容,日志内容不光能支持字符串哟,你们若是传递数组,对象等同样能够打印到console中。
* 第二个参数是日志类型,可选,若是没有指定日志类型默认类型为log, 第三个参数是自定样式,在这里写上你自定义css样式便可。
##配置
* 在载入SocketLog.class.php文件后,还能够对SocketLog进行一些配置。
* 例如:咱们若是想将程序的报错信息页输出到console,能够配置mysql
* 配置SocketLog也是用slog函数, 第一个参数传递配置项的数组,第二个参数设置为set_config
* 还支持其余配置项git
* optimize 参数若是设置为true, 能够在日志中看见利于优化参数,如:`[运行时间:0.081346035003662s][吞吐率:12.29req/s][内存消耗:346,910.45kb]`
* show_included_files 设置为true,能显示出程序运行时加载了哪些文件,好比咱们在分析开源程序时,若是不知道模板文件在那里, 每每看一下加载文件列表就知道模板文件在哪里了。
* error_handler 设置为true,能接管报错,将错误信息显示到浏览器console, 在开发程序时notice报错能让咱们快速发现bug,可是有些notice报错是不可避免的,若是让他们显示在页面中会影响网页的正常布局,那么就设置error_handler,让它显示在浏览器console中吧。 另外此功能结合php taint也是极佳的。 taint能自动检测出xss,sql注入, 若是只用php taint, 它warning报错只告诉了变量输出的地方,并不知道变量在那里赋值、怎么传递。经过SocketLog, 能看到调用栈,轻松对有问题变量进行跟踪。 更多taint的信息:http://www.laruence.com/2012/02/14/2544.html
* 设置client_id: 在chrome浏览器中,能够设置插件的Client_ID ,Client_ID是你任意指定的字符串。
* 设置client_id后能实现如下功能:
* 1,配置allow_client_ids 配置项,让指定的浏览器才能得到日志,这样就能够把调试代码带上线。 普通用户访问不会触发调试,不会发送日志。 开发人员访问就能看的调试日志, 这样利于找线上bug。 Client_ID 建议设置为姓名拼命加上随机字符串,这样若是有员工离职能够将其对应的client_id从配置项allow_client_ids中移除。 client_id除了姓名拼音,加上随机字符串的目的,以防别人根据你公司员工姓名猜想出client_id,获取线上的调试日志。
* 设置allow_client_ids示例代码:github
* 2, 设置force_client_id配置项,让后台脚本也能输出日志到chrome。 网站有可能用了队列,一些业务逻辑经过后台脚本处理, 若是后台脚本须要调试,你也能够将日志打印到浏览器的console中, 固然后台脚本不和浏览器接触,不知道当前触发程序的是哪一个浏览器,因此咱们须要强制将日志打印到指定client_id的浏览器上面。 咱们在后台脚本中使用SocketLog时设置force_client_id 配置项指定要强制输出浏览器的client_id 便可。
* 示例代码:web
##对数据库进行调试
* SocketLog还能对sql语句进行调试,自动对sql语句进行explain分析,显示出有性能问题的sql语句。 以下图所示。
* 图中显示出了三条sql语句 , 第一条sql语句字体较大,是由于它又性能问题, 在sql语句的后台已经标注Using filesort。 咱们还能够点击某个sql语句看到sql执行的调用栈,清楚的知道sql语句是如何被执行的,方便咱们分析程序、方便作开源程序的二次开发。图中第三条sql语句为被点开的状态。
* 用slog函数打印sql语句是,第二个参数传递为mysql或mysqli的对象便可。 示例代码:sql
后面会以OneThink为实例再对数据库调试进行演示。
* 注意,有时候在数据比较少的状况下,mysql查询不会使用索引,explain也会提示Using filesort等性能问题, 其实这时候并非真正有性能问题, 你须要自行进行判断,或者增长更多的数据再测试。
##对API进行调试
网站调用了API ,如何将API程序的调试信息也打印到浏览器的console中? 前面咱们讲了一个配置 force_client_id, 能将日志强制记录到指定的浏览器。 用这种方式也能够将API的调试信息打印到console中,可是force_client_id 只能指定一个client_id, 若是咱们的开发环境是多人共用,这种方式就不方便了。
其实只要将浏览器传递给网站的User-Agent 再传递给API, API程序中不用配置force_client_id, 也能识别当前访问程序的浏览器, 将日志打印到当前访问程序的浏览器, 咱们须要将SDK代码稍微作一下修改。 调用API的SDK,通常是用curl写的,增长下面代码能够将浏览器的User-Agent传递到API 。 chrome
##分析开源程序
有了SocketLog,咱们能很方便的分析开源程序,下面以OneThink为例, 你们能够在 http://www.onethink.cn/ 下载最新的OneThink程序。 安装好OneThink后,按下面步骤增长SocketLog程序。
* 将SocketLog.class.php复制到OneThink的程序目录中,你若是没有想好将文件放到哪一个子文件夹,暂且放到根目录吧。
* 编辑入口文件index.php, 再代码的最前面加载SocketLog.class.php ,并设置SocketLog
thinkphp
- 编辑ThinkPHP/Library/Think/Db/Driver/Mysqli.class.php 文件, 若是你用的数据库驱动类型不是mysqli,而是mysql,那么请打开Mysql.class.php, 找到执行sql语句的地方, 这个类中得execute 方法为一个执行sql语句的方法,大约在119行处,增长代码:
- 类中的query方法也是一个执行sql语句的地方, 一样须要增长上面的代码, 大约在92行增长slog($this->queryStr,$this->_linkID);
- 而后浏览网站看看效果: 经过console的日志,访问每一页咱们都知道程序干了什么,是一件很爽的事情。- 提示:另外一种更简单的方法,由于OneThink每次执行完sql语句都会调用$this->debug, 因此咱们能够把slog($this->queryStr,$this->_linkID); 直接写在 Db.class.php文件的debug方法中。 这样不论是mysqli仍是mysql驱动都有效。