KingKongFrog
KingKongFrog

Reputation: 14419

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();

Upvotes: 11

Views: 4239

Answers (2)

MathObsessed
MathObsessed

Reputation: 529

I don't have enough reputation to comment but just to improve this answer

$response = $client->post($uri, [
    RequestOptions::JSON => $postData,
    RequestOptions::ON_STATS => function (TransferStats $stats) use ($logger) {
        $formatter = new MessageFormatter('{"request":{"uri":"{uri}","body":{req_body}},"response":{"code":{code},"body":{res_body}},"time":'.$stats->getTransferTime().'}');
        $message = $formatter->format($stats->getRequest(), $stats->getResponse());

        $logger->info($message);
    },
]);

P.S.: This code is for Guzzle 7

Upvotes: 1

Shaun Bramley
Shaun Bramley

Reputation: 2047

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.

Upvotes: 4

Related Questions