aben1188 / socketlog
API、Ajax、微信调试工具,版本v2.2
Requires
- php: >=5.4.0
This package is auto-updated.
Last update: 2024-09-15 03:24:06 UTC
README
#说明
SocketLog适用于Ajax调试和API调试。举一个常见场景,使用SocketLog进行微信调试。在我们进行微信API开发时,如果API存在bug,微信只会提示“该公众账号暂时无法提供服务,请稍候再试”,我们无法得知API出了什么问题。有了SocketLog就不一样了,我们可以知道微信传递给API的参数,以及程序错误时也能看到错误信息(下方图片可能加载较慢,请耐心等待)。
- 正在运行的API存在bug,不能使用var_dump进行调试,因为这会影响客户端调用。将日志写入文件查看也不方便,尤其是带调用栈或大数据结构的文件日志,查看非常困难。这时使用SocketLog最佳,SocketLog通过WebSocket将调试日志打印到浏览器的console中。你还可以用它来分析开源程序,分析SQL性能,结合taint分析程序漏洞。
- Chrome插件安装:https://chrome.google.com/webstore/detail/socketlog/apkmbfpihjhongonfcgdagliaglghcod(如果无法正常访问此页面,你可以使用以下手动安装方法进行安装)
- 目录结构:
- chrome 目录是 chrome插件的源代码
- chrome.crx 文件是chrome插件的安装包,如果你无法从chrome应用商店安装,可以手动安装,在浏览器地址栏输入并打开:chrome://extensions/,然后将chrome.crx拖入即可安装。
- php 目录下的SocketLog.class.php是发送日志的类库,我们在发送日志时,需要载入这个类库然后调用函数slog即可。
- 效果展示:我们在浏览网站时,在浏览器console中就能知道程序做了什么,这对于二次开发产品非常有用。下面效果图在console中打印出浏览discuz程序时,执行的哪些sql语句,以及执行sql语句的调用栈。程序的warning、notice等错误信息也可以打印到console中。
#使用方法
-
首先,请在chrome浏览器上安装好插件。
-
安装服务端
npm install -g socketlog-server
,运行命令socketlog-server
即可启动服务。将会在本地启动一个websocket服务,监听端口是1229。如果想服务后台运行:socketlog-server > /dev/null &
。我们提供公用的服务端,需要去申请client_id:http://slog.thinkphp.cn/ -
如果你的服务器有防火墙,请开启1229和1116两个端口,这两个端口是socketlog要使用的。
-
在自己的程序中发送日志:
<?php include './php/slog.function.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样式即可。
##配置
-
在载入slog.function.php文件后,还可以对SocketLog进行一些配置。
-
例如:我们如果想将程序的报错信息页输出到console,可以配置
<?php include './php/slog.function.php'; slog(array( 'error_handler'=>true ),'config'); echo notice;//制造一个notice报错 slog('这里是输出的一般日志'); ?>
-
配置SocketLog也是用slog函数,第一个参数传递配置项的数组,第二个参数设置为config
-
还支持其他配置项
<?php include './php/slog.function.php'; slog(array( 'enable'=>true,//是否打印日志的开关 'host'=>'localhost',//websocket服务器地址,默认localhost 'optimize'=>false,//是否显示利于优化的参数,如果运行时间,消耗内存等,默认为false 'show_included_files'=>false,//是否显示本次程序运行加载了哪些文件,默认为false 'error_handler'=>false,//是否接管程序错误,将程序错误显示在console中,默认为false 'force_client_id'=>'',//日志强制记录到配置的client_id,默认为空 'allow_client_ids'=>array()////限制允许读取日志的client_id,默认为空,表示所有人都可以获得日志。 ) ,'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是你任意指定的字符串。
-
设置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/slog.function.php'; slog(array( 'force_client_id'=>'luofei_zfH5NbLn' ),'config'); slog('test'); `
##支持composer
-
使用composer安装命令
composer require luofei614/socketlog
-
直接调用静态方法
<?php require './vendor/autoload.php'; use think\org\Slog //配置socketlog Slog::config(array( 'enable'=>true,//是否打印日志的开关 'host'=>'localhost',//websocket服务器地址,默认localhost 'optimize'=>false,//是否显示利于优化的参数,如果运行时间,消耗内存等,默认为false 'show_included_files'=>false,//是否显示本次程序运行加载了哪些文件,默认为false 'error_handler'=>false,//是否接管程序错误,将程序错误显示在console中,默认为false 'force_client_id'=>'',//日志强制记录到配置的client_id,默认为空 'allow_client_ids'=>array()////限制允许读取日志的client_id,默认为空,表示所有人都可以获得日志。 )); Slog::log('log'); //一般日志 Slog::error('msg'); //错误日志 Slog::info('msg'); //信息日志 Slog::warn('msg'); //警告日志 Slog::trace('msg');// 输入日志同时会打出调用栈 Slog::alert('msg');//将日志以alert方式弹出 Slog::log('msg','color:red;font-size:20px;');//自定义日志的样式,第三个参数为css样式
##支持ThinkPHP ThinkPHP5后,在框架层集成了SocketLog,只需要设置配置即可使用
##对数据库进行调试
-
SocketLog还能对SQL语句进行调试,自动对SQL语句进行explain分析,显示出有性能问题的SQL语句。如下图所示。
-
图中显示出了三条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);
## 区分正式和开发环境
进入Chrome浏览器的“工具”-->“扩展程序”,点击SocketLog的“选项”进行设置。
## 分析开源程序
有了SocketLog,我们能很方便地分析开源程序,下面以OneThink为例,大家可以在 http://www.topthink.com/topic/2228.html 下载最新的OneThink程序。安装好OneThink后,按下面步骤增加SocketLog程序。
-
将SocketLog.class.php复制到OneThink的程序目录中,你如果没有想好将文件放到哪个子文件夹,暂且放到根目录吧。
-
编辑入口文件index.php,在代码的最前面加载slog.function.php,并设置SocketLog。
<?php include './slog.function.php'; slog(array( 'error_handler'=>true, 'optimize'=>true, 'show_included_files'=>true ),'config');
-
编辑ThinkPHP/Library/Think/Db/Driver.class.php 文件,在这个类中的execute 方法为一个执行sql语句的方法,增加代码:
slog($this->queryStr,$this->_linkID);
-
类中的query方法也是一个执行sql语句的地方,同样需要增加上面的代码
-
然后浏览网站看看效果:
通过console的日志,访问每一页我们都知道程序干了什么,是一件很爽的事情。
- 提示:另一种更简单的方法,因为OneThink每次执行完sql语句都会调用$this->debug,所以我们可以把slog($this->queryStr,$this->_linkID); 直接写在 Db.class.php文件的debug方法中。这样不管是mysqli还是mysql驱动都有效。
视频教程
http://edu.normalcoder.com/course/941
感谢猿团的张盛翔(诺墨)提供教程。
## 关于我
- 作者:@luofei614 新浪微博:http://weibo.com/luofei614
- 优伯立信创始人,ThinkPHP核心开发者之一,待过新浪云计算