Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to get the duration of an API call using Guzzle 6

Currently with Guzzle 6 it seems there's no out of the box way to get the duration of an API call. What's the best way to get this stat with any ordinary call using the code below.

I'm using the following code from How do you log all API calls using Guzzle 6

use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\MessageFormatter;
use Monolog\Logger;

$stack = HandlerStack::create();
$stack->push(
    Middleware::log(
        new Logger('Logger'),
        new MessageFormatter('{req_body} - {res_body}')
    )
);
$client = new \GuzzleHttp\Client(
    [
        'base_uri' => 'http://httpbin.org',
        'handler' => $stack,
    ]
);

echo (string) $client->get('ip')->getBody();
like image 824
KingKongFrog Avatar asked Sep 22 '15 21:09

KingKongFrog


People also ask

How do I get data from guzzle response?

Both request and response messages can contain a body. You can check to see if a request or response has a body using the getBody() method: $response = GuzzleHttp\get('http://httpbin.org/get'); if ($response->getBody()) { echo $response->getBody(); // JSON string: { ... } }

Is guzzle better than cURL?

The main benefits of using Guzzle over cURL is the API it offers, which results in more concise and readable code. For example look at the difference between the code in this question and the accepted answer, the cURL code is much more verbose that the Guzzle implementation.

How do I set timeout on guzzle?

If you have a queued job that uses Guzzle to make a request, make sure you set a timeout value for the guzzle request: (new \GuzzleHttp\Client())->get('http://domain.com', [ 'timeout' => 15 ]);


1 Answers

I refer you to the 'on_stats' request option Guzzle Docs - Request Options and the TransferStats object

To implement this you would modify your get request to use request options. It would be something like the following:

// get($uri, $options) proxies to request($method, $uri, $options)
// request($method, $uri, $options) proxies to requestAsync($method, $uri, $options)
// and sets the $options[RequestOptions::SYNCHRONOUS] to true
// and then waits for promises to resolve returning a Psr7\http-message\ResponseInterface instance

$response = $client->get($uri, [
    'on_stats'  => function (TransferStats $stats) use ($logger) {
        // do something inside the callable.
        echo $stats->getTransferTime() . "\n";
        $logger->debug('Request' . $stats->getRequest() . 
                       'Response' . $stat->getResponse() .
                       'Tx Time' . $stat->getTransferTime()
        );
    },
]);
echo $response->getBody();

**Note: I'm certain there are ways of ensuring the log is formatted nicer, however, this was to serve as a proof of concept.

The TransferStats are generated and used within the individual handlers, and at this time are not made available by the handler to the stack. As a result they are not available for consumption within the invidual middlewares placed upon the stack.

like image 119
Shaun Bramley Avatar answered Sep 28 '22 23:09

Shaun Bramley