Laravel - 将 Guzzle 请求记录到文件

shy*_*.me 3 logging laravel guzzle

在开发一个项目时,我发现第三方 API 可以在 Postman 中运行,但不能在 Guzzle Client 中运行。

调试 Guzzle 请求可能很困难,那么有没有什么方法可以记录 Guzzle 客户端发出的所有请求?

shy*_*.me 5

太长了;

\n\n

\xe2\x80\x99 有一种简单的方法来记录所有 Guzzle 请求,方法是将第二个参数传递给客户端,然后它将记录所有请求。但是,如果您有许多使用 Guzzle 客户端向第三方服务器发送请求的方法,那么 \xe2\x80\x99 就会变得丑陋。我\xe2\x80\x99已经使用 Laravel\xe2\x80\x99s 服务容器完成了它。

\n\n

通过 Laravel\xe2\x80\x99s 服务容器的长途旅行

\n\n

当我在项目中使用 Guzzle 客户端并使用处理程序记录所有请求时,它看起来不错。但后来在许多不同的类中有很多方法,所以我必须在每个地方编写记录器逻辑。然后我想为什么不\xe2\x80\x99t 利用 Laravel\xe2\x80\x99s服务容器并绑定一个对象一次并在任何地方使用它。

\n\n

Here\xe2\x80\x99s 我是如何做到的。在您的AppServiceContainer.php\xe2\x80\x99s 引导方法中,我们将添加所有代码。然后在控制器中我们将使用我们的客户端对象。

\n\n

将此 use 语句添加到文件顶部AppServiceContainer.php

\n\n
use GuzzleHttp\\Client;\nuse GuzzleHttp\\HandlerStack;\nuse GuzzleHttp\\MessageFormatter;\nuse GuzzleHttp\\Middleware;\nuse Illuminate\\Support\\ServiceProvider;\nuse Monolog\\Handler\\RotatingFileHandler;\nuse Monolog\\Logger;\n
Run Code Online (Sandbox Code Playgroud)\n\n

将以下代码添加到您的 AppServiceContainer.php\xe2\x80\x99sboot方法中

\n\n
/**\n * Bootstrap any application services.\n *\n * @return void\n */\npublic function boot()\n    {\n        $this->app->bind(\'GuzzleClient\', function () {\n\n            $messageFormats = [\n                \'REQUEST: {method} - {uri} - HTTP/{version} - {req_headers} - {req_body}\',\n                \'RESPONSE: {code} - {res_body}\',\n            ];\n\n            $stack = HandlerStack::create();\n\n            collect($messageFormats)->each(function ($messageFormat) use ($stack) {\n                // We\'ll use unshift instead of push, to add the middleware to the bottom of the stack, not the top\n                $stack->unshift(\n                    Middleware::log(\n                        with(new Logger(\'guzzle-log\'))->pushHandler(\n                            new RotatingFileHandler(storage_path(\'logs/guzzle-log.log\'))\n                        ),\n                        new MessageFormatter($messageFormat)\n                    )\n                );\n            });\n\n            return function ($config) use ($stack){\n                return new Client(array_merge($config, [\'handler\' => $stack]));\n            };\n        });\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

解释

\n\n

如果您注意到上面的代码,在 boot 方法的第一行中,我们告诉 Laravel 我们希望将此代码注册为服务容器中的 GuzzleClient。

\n\n

在最后一个 return 语句中,我们返回一个接受一个参数的函数$config。我们使用这个函数作为代理,以便我们可以向它传递一个参数,并且可以在客户端对象中使用。

\n\n
return function ($config) use ($stack){\n      return new Client(array_merge($config, [\'handler\' => $stack]));\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

其余代码正在构建 Guzzle\xe2\x80\x99s 处理程序对象,以将所有请求记录到guzzle-log.log使用 Monolog 库的 Logger 对象调用的文件中。如果您启用了每日日志,则会将日期附加到文件名中,例如guzzle-log-2019-08-11.log。\n用法

\n\n

我们已经将对象绑定到服务容器,现在是时候在代码中的任何地方使用这个容器了,并使其看起来干净。

\n\n

出于演示目的,我直接在routes/web.php文件中使用了它。您可以在任何地方使用。

\n\n
 Route::get(\'/\', function () {\n\n    $client = app(\'GuzzleClient\')([\'base_uri\' => \'http://httpbin.org/\']);\n\n    $request = $client->get(\'get\',[\n        \'query\' => [\'foo\'=>\'bar\', \'baz\' => \'baz2\'] ,\n        \'headers\' => [ \'accept\' =>  \'application/json\']\n    ]);\n    $response = json_decode((string) $request->getBody());\n    return response()->json($response);\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如你所看到的,我\xe2\x80\x99m$client使用app()助手创建了一个对象。您还可以传递 Guzzle 客户端支持的任何有效参数数组作为第二个参数。这里我\xe2\x80\x99已经通过了base_uri

\n\n

日志文件条目

\n\n

资料来源:http ://shyammakwana.me/laravel/laravel-log-guzzle-requests-to-file-using-service-container.html

\n