# 什么是SocketLog?
罗飞大神开发的一个php语言用的调试工具。由服务端和客户端插件及php扩展类组成。
# SocketLog有什么特色?
- SocketLog通过websocket将调试日志打印到浏览器的console中。
适合Ajax调试和API调试, 举一个常见的场景,用SocketLog来做微信调试, 我们在做微信API开发的时候,如果API有bug,微信只提示“改公众账号暂时无法提供服务,请稍候再试” ,我们根本不知道API出来什么问题。 有了SocketLog就不一样了, 我们可以知道微信给API传递了哪些参数, 程序有错误我们也能看见错误信息(下方有张图片,可能加载慢,请耐心等待一下)
![2015-05-12/55514f02e9b31](http://box.kancloud.cn/2015-05-12_55514f02e9b31.png)
- 配置allow_client_ids 配置项,让指定的浏览器才能获得日志
- 方便调试API
- 对数据库进行调试
- 分析开源项目
- 结合taint分析程序漏洞
# 安装
1.客户端
<https://chrome.google.com/webstore/detail/socketlog/apkmbfpihjhongonfcgdagliaglghcod> (如果不能正常访问这个页面,你可以用下面手动安装的方法进行安装)
目录结构:
chrome 目录是 chrome插件的源代码
chrome.crx 文件是chrome插件的安装包, 如果你无法从chrome应用商店安装,可进行手动安装, 浏览器地址栏输入并打开: chrome://extensions/ ,然后将chrome.crx拖入即可安装。
2.socket端
启用Websocket服务,该服务是nodejs写的,在server目录下,请先确保你的环境已经安装nodejs, 启动Websocket服务运行命令 node server/index.js , 将会在本地起一个websocket服务 ,监听端口是1229 。 如果想服务后台运行: nohup node server/index.js > /dev/null &
3.php程序
php 目录下的`SocketLog.class.php`是发送日志的类库,我们在发送日志的时候,需要载入这个类库然后调用函数slog即可。
# 使用
## 在自己的程序中发送日志:
~~~
<?php
include './php/SocketLog.class.php';
slog('hello world');
?>
~~~
## 用slog函数发送日志, 支持多种日志类型:
~~~
slog('msg','log'); //一般日志
slog('msg','error'); //错误日志
slog('msg','info'); //信息日志
slog('msg','warn'); //警告日志
slog('msg','trace');// 输入日志同时会打出调用栈
slog('msg','alert');//将日志以alert方式弹出
slog('msg','log','color:red;font-size:20px;');//自定义日志的样式,第三个参数为css样式
~~~
slog函数支持三个参数:
第一个参数是日志内容,日志内容不光能支持字符串哟,大家如果传递数组,对象等一样可以打印到console中。
第二个参数是日志类型,可选,如果没有指定日志类型默认类型为log。
第三个参数是自定样式,在这里写上你自定义css样式即可。
# 配置
在载入SocketLog.class.php文件后,还可以对SocketLog进行一些配置。
例如:我们如果想将程序的报错信息页输出到console,可以配置
~~~
<?php
include './php/SocketLog.class.php';
slog(array(
'error_handler'=>true
),'set_config');
echo notice;//制造一个notice报错
slog('这里是输出的一般日志');
?>
~~~
配置SocketLog也是用slog函数, 第一个参数传递配置项的数组,第二个参数设置为set_config
~~~
<?php
include './php/SocketLog.class.php';
slog(array(
'host'=>'localhost',//websocket服务器地址,默认localhost
'port'=>'1229',//websocket服务器端口,默认端口是1229
'optimize'=>false,//是否显示利于优化的参数,如果运行时间,消耗内存等,默认为false
'show_included_files'=>false,//是否显示本次程序运行加载了哪些文件,默认为false
'error_handler'=>false,//是否接管程序错误,将程序错误显示在console中,默认为false
'force_client_id'=>'',//日志强制记录到配置的client_id,默认为空
'allow_client_ids'=>array()////限制允许读取日志的client_id,默认为空,表示所有人都可以获得日志。
)
,'set_config');
?>
~~~
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`是你任意指定的字符串。
![2015-05-13/5552a1a758817](http://box.kancloud.cn/2015-05-13_5552a1a758817.png)
设置client_id后能实现以下功能:
1,配置`allow_client_ids` 配置项,让指定的浏览器才能获得日志,这样就可以把调试代码带上线。 普通用户访问不会触发调试,不会发送日志。 开发人员访问就能看的调试日志, 这样利于找线上bug。 `Client_ID` 建议设置为姓名拼命加上随机字符串,这样如果有员工离职可以将其对应的`client_id`从配置项`allow_client_ids`中移除。 `client_id`除了姓名拼音,加上随机字符串的目的,以防别人根据你公司员工姓名猜测出`client_id`,获取线上的调试日志。
设置`allow_client_ids`示例代码:
~~~
slog(array(
'allow_client_ids'=>array('luofei_zfH5NbLn','easy_DJq0z80H')
),'set_config')
~~~
2, 设置`force_client_id`配置项,让后台脚本也能输出日志到chrome。 网站有可能用了队列,一些业务逻辑通过后台脚本处理, 如果后台脚本需要调试,你也可以将日志打印到浏览器的console中, 当然后台脚本不和浏览器接触,不知道当前触发程序的是哪个浏览器,所以我们需要强制将日志打印到指定`client_id`的浏览器上面。 我们在后台脚本中使用SocketLog时设置`force_client_id` 配置项指定要强制输出浏览器的`client_id` 即可。
示例代码:
~~~
<?php
include './php/SocketLog.class.php';
slog(array(
'force_client_id'=>'luofei_zfH5NbLn'
),'set_config');
slog('test'); `
~~~
# 对数据库进行调试
* SocketLog还能对sql语句进行调试,自动对sql语句进行explain分析,显示出有性能问题的sql语句。 如下图所示。
![enter image description here][3]
* 图中显示出了三条sql语句 , 第一条sql语句字体较大,是因为它又性能问题, 在sql语句的后台已经标注Using filesort。 我们还可以点击某个sql语句看到sql执行的调用栈,清楚的知道sql语句是如何被执行的,方便我们分析程序、方便做开源程序的二次开发。图中第三条sql语句为被点开的状态。
* 用slog函数打印sql语句是,第二个参数传递为mysql或mysqli的对象即可。 示例代码:
~~~
$link=mysql_connect( 'localhost:3306' , 'root' , '123456' , true ) ;
mysql_select_db('kuaijianli',$link);
$sql="SELECT * FROM `user`";
slog($sql,$link);
~~~
后面会以OneThink为实例再对数据库调试进行演示。
通过上面的方法,socketlog还能自动为你检测没有where语句的sql操作,然后自动提示你。
* 注意,有时候在数据比较少的情况下,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 。
~~~
$headers=array();
if(isset($_SERVER['HTTP_USER_AGENT']))
{
$headers[]='User-Agent: '.$_SERVER['HTTP_USER_AGENT'];
}
if(isset($_SERVER['HTTP_SOCKETLOG']))
{
$headers[]='Socketlog: '.$_SERVER['HTTP_SOCKETLOG'];
}
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
~~~
## 在Freelog案列中的应用
首先,入口包含类库,和设置好配置
![2015-05-13/555315f76e6ea](http://box.kancloud.cn/2015-05-13_555315f76e6ea.png)
然后,修改了数据库驱动文件`/ThinkPHP/Library/Think/Db/Driver.class.php`的 query 和execute 方法
![2015-05-13/55531725e19d8](http://box.kancloud.cn/2015-05-13_55531725e19d8.png)
![2015-05-13/55531750b749a](http://box.kancloud.cn/2015-05-13_55531750b749a.png)
然后浏览网站看看效果:
![2015-05-13/555318285fa27](http://box.kancloud.cn/2015-05-13_555318285fa27.png)
通过console的日志,访问每一页我们都知道程序干了什么,是一件很爽的事情。
- 序
- 前言
- 内容简介
- 目录
- 基础知识
- 起步
- 控制器
- 模型
- 模板
- 命名空间
- 进阶知识
- 路由
- 配置
- 缓存
- 权限
- 扩展
- 国际化
- 安全
- 单元测试
- 拿来主义
- 调试方法
- 调试的步骤
- 调试工具
- 显示trace信息
- 开启调试和关闭调试的区别
- netbeans+xdebug
- Socketlog
- PHP常见错误
- 小黄鸭调试法,每个程序员都要知道的
- 应用场景
- 第三方登录
- 图片处理
- 博客
- SAE
- REST实践
- Cli
- ajax分页
- barcode条形码
- excel
- 发邮件
- 汉字转全拼和首字母,支持带声调
- 中文分词
- 浏览器useragent解析
- freelog项目实战
- 需求分析
- 数据库设计
- 编码实践
- 前端实现
- rest接口
- 文章发布
- 文件上传
- 视频播放
- 音乐播放
- 图片幻灯片展示
- 注册和登录
- 个人资料更新
- 第三方登录的使用
- 后台
- 微信的开发
- 首页及个人主页
- 列表
- 归档
- 搜索
- 分页
- 总结经验
- 自我提升
- 进行小项目的锻炼
- 对现有轮子的重构和移植
- 写技术博客
- 制作视频教程
- 学习PHP的知识和新特性
- 和同行直接沟通、交流
- 学好英语,走向国际
- 如何参与
- 浏览官网和极思维还有看云
- 回答ThinkPHP新手的问题
- 尝试发现ThinkPHP的bug,告诉官方人员或者push request
- 开发能提高效率的ThinkPHP工具
- 尝试翻译官方文档
- 帮新手入门
- 创造基于ThinkPHP的产品,进行连带推广
- 展望未来
- OneThink
- ThinkPHP4
- 附录