在 thinkphp 5.1 中集成 guzzle 请求日志中间件,需通过 handlerstack 注入自定义中间件,捕获请求响应全过程并用 log::write() 记录;须脱敏敏感头、控制响应体大小、复用单例客户端,并按环境开关日志。

在 ThinkPHP 5.1 中集成 Guzzle 并为其添加请求日志中间件,核心在于利用 Guzzle 的 HandlerStack 注入自定义中间件,捕获请求与响应全过程,再通过 ThinkPHP 的日志系统(如 Log::write())持久化记录。不需修改 Guzzle 源码,也不依赖外部包,纯原生方式即可实现。
配置 Guzzle 实例并挂载日志中间件
在应用中创建 Guzzle 客户端时,需手动构建 HandlerStack,将日志中间件推入栈顶(或指定位置)。中间件函数接收 $handler,返回一个闭包,该闭包在实际请求执行前后可访问 $request 和 $response(或异常)。
- 使用
HandlerStack::create()初始化栈,避免直接操作默认 handler - 中间件中建议用
try/catch包裹$handler($request, $options),确保异常也能被捕获并记录 - 日志内容至少包含 URL、方法、请求头(脱敏敏感字段)、响应状态码、耗时(毫秒),可选记录请求体和响应体(注意大小限制和敏感信息)
日志中间件编写要点
中间件本质是返回 callable 的函数。关键逻辑:记录发起前时间戳 → 执行下游 handler → 记录响应/异常 → 计算耗时 → 格式化写入日志。
- 对 Authorization、Cookie、X-Auth-Token 等敏感请求头做掩码处理,例如替换为
[hidden] - 响应体过大(如 >1KB)时建议截断或仅记录长度,避免日志文件暴涨
- 推荐使用 ThinkPHP 的
Log::record()+Log::save()组合,或直接调用Log::write($data, 'info', 'guzzle')指定日志通道
在业务中统一复用客户端
避免每次请求都新建 Guzzle 实例。建议在服务提供者(如 app/provider/HttpServiceProvider.php)中注册单例客户端,并预置好带日志中间件的 HandlerStack。
- 可通过容器绑定
GuzzleHttp\Client::class,注入自定义配置 - 若项目已使用
thinkphp-guzzle等扩展,确认其是否支持中间件扩展;否则优先手写,更可控 - 调试阶段可临时开启全量日志;上线后建议按环境配置开关,例如仅
APP_DEBUG=true时启用
验证与排查常见问题
启用后若无日志输出,先检查中间件是否真正被调用(可在中间件内加 dump('log middleware hit') 临时验证),再逐项排查:
- 日志通道是否启用?
config/log.php中'guzzle'通道是否存在且路径可写 - 中间件是否被覆盖?确认未在其他地方重新 new Client 而绕过自定义 stack
- 异步请求(
sendAsync)需注意:中间件同样生效,但日志写入发生在 Promise resolve/reject 之后,需确保事件循环未提前退出
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










