omnipay icon indicating copy to clipboard operation
omnipay copied to clipboard

interception of all raw requests and responses

Open 4n70w4 opened this issue 7 years ago • 8 comments
trafficstars

Hi, tell me how can I make any handler and register it in your library or implement it through the http-client so that I can log all the requests and answers? Do you have any idea how this can be implemented without editing the code? This is very useful for developing and debugging, as well as for investigations exceptions in production.

4n70w4 avatar Sep 19 '18 21:09 4n70w4

I tried to create a \GuzzleHttp\Client object and add a handler to it.

But the call to Omnipay::create($gateway_name, $client); rejects my object because \GuzzleHttp\Client does not implement your interface \Omnipay\Common\Http\ClientInterface.

Ok. I wrap my object through your \Omnipay\Common\Http\Client($client); But getting an exception: URI must be a string or UriInterface from: vendor/guzzlehttp/psr7/src/functions.php:62

$logger = (new \Monolog\Logger('omnipay'))->pushHandler(
	new \Monolog\Handler\RotatingFileHandler('/var/www/app/current/var/logs/omnipay.log')
);

$s = \GuzzleHttp\Middleware::log($logger, new \GuzzleHttp\MessageFormatter(MessageFormatter::DEBUG));

$handlerStack = \GuzzleHttp\HandlerStack::create();
$handlerStack->push($s);
$client = new \GuzzleHttp\Client(['handler' => $handlerStack]);

$wrap = new \Omnipay\Common\Http\Client($client);

$gateway = Omnipay::create($gateway_name, $wrap);

4n70w4 avatar Sep 20 '18 22:09 4n70w4

However, I can directly (bypassing your Omnipay::create() factory) create a gateway object and pass my \GuzzleHttp\Client object to it! Although it does not implement the \Omnipay\Common\Http\Client Interface.

The request will succeed and the logging to the file will be executed! But without the factory is not convenient, because need a lot of gateways.

$logger = (new \Monolog\Logger('omnipay'))->pushHandler(
	new \Monolog\Handler\RotatingFileHandler('/var/www/app/current/var/logs/omnipay.log')
);

$s = \GuzzleHttp\Middleware::log($logger, new \GuzzleHttp\MessageFormatter(MessageFormatter::DEBUG));

$handlerStack = \GuzzleHttp\HandlerStack::create();
$handlerStack->push($s);
$client = new \GuzzleHttp\Client(['handler' => $handlerStack]);

$gateway = new \Omnipay\Bitcoin\Gateway($client);

Tell me where I made a mistake, or in your library something is wrong.

4n70w4 avatar Sep 20 '18 22:09 4n70w4

@Namek @greydnls

you had a similar discussion. Do you have a solution to this question?

4n70w4 avatar Sep 21 '18 21:09 4n70w4

sorry, it's been super long time ago, I even (gladly) don't work with PHP anymore

Namek avatar Sep 27 '18 08:09 Namek

Bump! Dealing with the same use scenario (setting a handler to be able to log the requests & responses) and facing the exact same issue.

nocive avatar Nov 09 '18 16:11 nocive

Ok, I figured this out, you have to instantiate the php-http/guzzle6 adapter instead of guzzle's client directly. For those out there potentially struggling with the same, took me 2 days to figure this out, so I hope this saves you the trouble:

public function __construct($httpClient = null, RequestFactory $requestFactory = null)
{
    $stack = HandlerStack::create();
    $stack->push(Middleware::log(new \Monolog\Logger('ffs'), new MessageFormatter()));
    $httpClient = new \Http\Adapter\Guzzle6\Client(new \GuzzleHttp\Client(['handler' => $stack]));

    parent::__construct($httpClient, $requestFactory);
}

Notice the client instantiation, you have to instantiate the guzzle adapter and feed it the guzzle client.

cc @4n70w4

nocive avatar Nov 12 '18 16:11 nocive

@nocive does it work in production?

4n70w4 avatar Dec 06 '18 12:12 4n70w4

@4n70w4 sure, why wouldn’t it? That should be up to your logger configuration, not guzzle or omnipay.

In the example above you have to replace \Monolog\Logger(‘ffs’) with your own logger instance.

nocive avatar Dec 06 '18 13:12 nocive