Ngrok,老早就了解过了,但是在平时没有怎么用过,只知道外网可以访问内网,关于所说的微信支付等调试,应用场景,确实没有深入地想一想,然后就没动过了...
今天,看了下银联支付,搜索到一篇比较好的介绍文章,再次看到了 ngrok。外加自己也做了微信、支付宝支付,稍微想了下:
同步通知是可以回跳到本地页面的
异步通知,得支付平台给咱们本地发起 post 请求,这个是访问不到本地的,所以,才需要借助 ngrok 来让外网访问本地内网。(就这么多想了一步,就了解了应用场景了)
Ngrok 最初了解时,还是群里的 sunny 同学发的文章才了解到的,现在他还做了国内的 ngrok 服务:
https://www.ngrok.cc/
这里引用下他的 ngrok 搭建文章:
https://www.sunnyos.com/article-show-48.html
文章第一段就提到了:
『如何通过SocketLog进行web和微信开发调试』
扫了一眼,平常我们微信调试,一些调试返回的内容,得需要往日志中写入,来分析;而 SocketLog 应该是借助 socket 来往浏览器中写入,然后在 console 控制台来显示。
/*
浏览器支持 socket 连接,具体 SocketLog 内容我还没有看,包括 『如何通过SocketLog进行web和微信开发调试』 我也仅仅看了下日志输出到浏览器,不知道自己判断是否正确。
为什么我要写这些东西呢?
就是想说下,好多知识是有联系的,也是需要积累的。例如,我之前没做过支付,异步通知是啥?不懂。Socket 没了解过,也就不会意识到 SocketLog 可能是做什么的。以后还是得多思考、多学习!自己底层的好多东西,了解的太少了!
*/
接下来开始 SocketLog 的学习:
SocketLog github 地址:
https://github.com/luofei614/SocketLog
如何通过SocketLog进行web和微信开发调试
https://www.sunnyos.com/article-show-35.html
看了下,文档很详细,我就照着简单总结过一遍:
使用:
1.安装 chrome 插件:
1>在线安装:
https://chrome.google.com/webstore/detail/socketlog/apkmbfpihjhongonfcgdagliaglghcod
2>手动安装:
github 上下载 chrome.crx
浏览器输入:chrome://extensions
将chrome.crx 拖入打开页面
2.安装服务端:
npm install -g socketlog-server
运行 socketlog-server 启动服务,在本地起一个 websocket 服务,监听 1229 端口
后台运行:socketlog-server > /dev/null &
注意:
服务器如果有防火墙,需要开启:1229 和 1116 端口
3.在程序中记录日志
include './php/slog.function.php';
slog('hello world');
php 中 socketlog 的用法:
1.引入 socketlog:
include './php/slog.function.php';
2.方法调用:
1>记录日志
slog('日志内容', '日志类型', '自定义CSS样式');
示例:
slog('hello world', 'log', 'color: red; font-size: 20px;');
支持的日志类型:
log // 一般日志(默认日志类型)
error // 错误日志
info // 信息日志
warn // 警告日志
trace // 输入日志同时会打出调用栈
alert // 将日志以 alert 方式弹出
2>SocketLog 日志配置:
slog([配置数组], 'config');
示例:
slog([
'error_handler' => true,
'enable' => true,
], config);
支持的配置项:
enable - 是否打印日志
host - websocket 服务器地址,默认为 localhost
optimize - 是否显示利于优化的参数,如:运行时间、消耗内存等,默认为 false
show_included_files - 是否显示本次程序运行加载了哪些文件,默认为 false
error_handler - 是否接管程序错误,将程序错误显示在 console 中,默认为 false
force_client_id - 日志强制记录到配置的 client_id,默认为空
allow_client_ids - 限制允许读取日志的 client_id,默认为空,表示所有人都可以获得日志
个别配置详细解释:
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, 能看到调用栈,轻松对有问题变量进行跟踪。
allow_client_ids
让指定的浏览器才能获得日志,这样就可以把调试代码带上线。 普通用户访问不会触发调试,不会发送日志。 开发人员访问就能看的调试日志, 这样利于找线上bug。 Client_ID 建议设置为姓名拼命加上随机字符串,这样如果有员工离职可以将其对应的client_id从配置项allow_client_ids中移除。 client_id除了姓名拼音,加上随机字符串的目的,以防别人根据你公司员工姓名猜测出client_id,获取线上的调试日志
slog([
'allow_client_ids' => ['xxx', 'yyy'],
], 'config');
force_client_id
让后台脚本也能输出日志到chrome。 网站有可能用了队列,一些业务逻辑通过后台脚本处理, 如果后台脚本需要调试,你也可以将日志打印到浏览器的console中, 当然后台脚本不和浏览器接触,不知道当前触发程序的是哪个浏览器,所以我们需要强制将日志打印到指定client_id的浏览器上面。 我们在后台脚本中使用SocketLog时设置force_client_id 配置项指定要强制输出浏览器的client_id 即可。
slog([
'force_client_id' => 'xxx',
], 'config');
注意:
allow_client_ids 和 force_client_id 配置项,需要在 chrome 浏览器中,设置插件的 Client_ID。(就是我们第一步安装的 chrome 插件,里面链接 socket 服务器,设置的 Client_ID)
支持 composer 使用:
安装:
composer require luofei614/socketlog
使用静态方法来调用:
use think\org\Slog;
// 配置
Slog::config([
'error_handler' => true,
'enable' => true,
]);
// 记录日志
Slog::log('日志');
Slog::error('日志');
Slog::info('日志');
Slog::warn('日志');
Slog::trace('日志');
Slog::alert('日志');
支持ThinkPHP ThinkPHP5后, 在框架层集成了SocketLog ,只需要设置配置即可用
(这个未了解过)
对数据库进行调试
看文档
对 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的“选项”进行设置
(发现打开后的链接是:chrome-extension://apkmbfpihjhongonfcgdagliaglghcod/options.html)
分析开源程序
看文档
使用结果:
1.我使用的是 Laravel 框架,通过 composer 安装了 socketlog,自动加载是有问题的!
修复:
查看 vendor/luofei614/socketlog/
composer.json:
"autoload": {
"psr-4": {
"think\\slog\\": "php/"
}
}
1>php/slog.php 源码:
namespace think;
改为
namespace think\slog;
2>代码中使用:
use think\org\Slog;
改为
use think\slog\Slog;
2.后台脚本的 socketlog 输出,以下 2 个条件必须配置:
1>chrome 插件设置 client_id
2>代码中配置 force_client_id
3.关于文档中说的 API 的调试
1>并不是我们针对单个 api 接口来调试,例如,通过 postman 来调试 API 的返回结果。这本身就能得到结果,错误还是正确
2>也不是我们请求一个页面,该页面调用了其他 API 接口(不管是第三方还是我们平台自身)。我们可以将返回结果,通过 SocketLog 来输出
3>而是我们请求一个页面,该页面调用了其他 API 接口(而这些 API 接口也是我们平台自身的,第三方我们也无法操作)。我们在这些 API 的方法中,使用了 Socketlog 来输出一些调试信息
这样才解释了文档中,所说的需要将访问网页中的 $_SERVER['HTTP_USER_AGENT'] 和 $_SERVER['HTTP_SOCKETLOG'],设置到 curl 的 header 头中
$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);
4.可以简单看看 socketlog 源码:
vendor/luofei614/socketlog/
chrome - 谷歌浏览器插件,监听了 socket 等,添加了 HTTP_SOCKETLOG 头(js 写的,大概还能看懂)
php - 函数方式 + composer 方式,我们 php 代码使用
server - node 插件,启动了 socket 服务和 http 服务
5.SocketLog 的输出,会输出到当前打开的浏览器的 tab 页的 console 中