TLDR;
有一种简单的方法可以通过将第二个参数传递给客户端来记录所有 Guzzle 请求,然后它将记录所有请求。但如果你有很多方法使用 Guzzle Client 向第三方服务器发送请求,那么这种方式就很丑陋。我已经使用 Laravel 的服务容器完成了它。
通过 Laravel 服务容器进行长途旅行
当我在项目中使用 Guzzle 客户端并使用处理程序记录所有请求时,它看起来不错。但后来在许多不同的类中有很多方法,所以我必须在每个地方编写记录器逻辑。然后我想为什么不利用 Laravel 的服务容器并绑定一个对象一次并在任何地方使用它。
我是这样做的。在你的AppServiceContainer.php
的 boot 方法中,我们将添加所有代码。然后在控制器中我们将使用我们的客户端对象。
在上面添加这个 use 语句AppServiceContainer.php
file.
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\MessageFormatter;
use GuzzleHttp\Middleware;
use Illuminate\Support\ServiceProvider;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
将以下代码添加到您的应用程序服务Container.phpboot
method
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->app->bind('GuzzleClient', function () {
$messageFormats = [
'REQUEST: {method} - {uri} - HTTP/{version} - {req_headers} - {req_body}',
'RESPONSE: {code} - {res_body}',
];
$stack = HandlerStack::create();
collect($messageFormats)->each(function ($messageFormat) use ($stack) {
// We'll use unshift instead of push, to add the middleware to the bottom of the stack, not the top
$stack->unshift(
Middleware::log(
with(new Logger('guzzle-log'))->pushHandler(
new RotatingFileHandler(storage_path('logs/guzzle-log.log'))
),
new MessageFormatter($messageFormat)
)
);
});
return function ($config) use ($stack){
return new Client(array_merge($config, ['handler' => $stack]));
};
});
}
解释
如果您注意到上面的代码,在 boot 方法的第一行中,我们告诉 Laravel 我们希望将此代码注册为服务容器中的 Guzzle 客户端。
在最后一个 return 语句中,我们返回一个接受一个参数的函数$config
。我们使用这个函数作为代理,以便我们可以向它传递一个参数,并且可以在客户端对象中使用。
return function ($config) use ($stack){
return new Client(array_merge($config, ['handler' => $stack]));
};
其余代码正在构建 Guzzle 的处理程序对象,以将所有请求记录到名为guzzle-log.log
使用 Monolog 库的 Logger 对象。如果您启用了每日日志,则会将日期附加到文件名中,例如guzzle-log-2019-08-11.log
.
Usage
我们已经将对象绑定到服务容器,现在是时候在代码中的任何地方使用这个容器,并使其看起来干净了。
为了演示目的,我直接使用它routes/web.php
文件。您可以在任何地方使用。
Route::get('/', function () {
$client = app('GuzzleClient')(['base_uri' => 'http://httpbin.org/']);
$request = $client->get('get',[
'query' => ['foo'=>'bar', 'baz' => 'baz2'] ,
'headers' => [ 'accept' => 'application/json']
]);
$response = json_decode((string) $request->getBody());
return response()->json($response);
});
正如你所看到的,我正在制作一个物体$client
using app()
帮手。您还可以传递 Guzzle 客户端支持的任何有效参数数组作为第二个参数。这里我已经过去了base_uri
.
Source: http://shyammakwana.me/laravel/laravel-log-guzzle-requests-to-file-using-service-container.html http://shyammakwana.me/laravel/laravel-log-guzzle-requests-to-file-using-service-container.html