/usr/share/php/Guzzle/Plugin/Log/LogPlugin.php is in php-guzzle 3.7.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | <?php
namespace Guzzle\Plugin\Log;
use Guzzle\Common\Event;
use Guzzle\Log\LogAdapterInterface;
use Guzzle\Log\MessageFormatter;
use Guzzle\Log\ClosureLogAdapter;
use Guzzle\Http\EntityBody;
use Guzzle\Http\Message\EntityEnclosingRequestInterface;
use Guzzle\Http\Message\Response;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Plugin class that will add request and response logging to an HTTP request.
*
* The log plugin uses a message formatter that allows custom messages via template variable substitution.
*
* @see MessageLogger for a list of available log template variable substitutions
*/
class LogPlugin implements EventSubscriberInterface
{
/** @var LogAdapterInterface Adapter responsible for writing log data */
private $logAdapter;
/** @var MessageFormatter Formatter used to format messages before logging */
protected $formatter;
/** @var bool Whether or not to wire request and response bodies */
protected $wireBodies;
/**
* @param LogAdapterInterface $logAdapter Adapter object used to log message
* @param string|MessageFormatter $formatter Formatter used to format log messages or the formatter template
* @param bool $wireBodies Set to true to track request and response bodies using a temporary
* buffer if the bodies are not repeatable.
*/
public function __construct(
LogAdapterInterface $logAdapter,
$formatter = null,
$wireBodies = false
) {
$this->logAdapter = $logAdapter;
$this->formatter = $formatter instanceof MessageFormatter ? $formatter : new MessageFormatter($formatter);
$this->wireBodies = $wireBodies;
}
/**
* Get a log plugin that outputs full request, response, and curl error information to stderr
*
* @param bool $wireBodies Set to false to disable request/response body output when they use are not repeatable
* @param resource $stream Stream to write to when logging. Defaults to STDERR when it is available
*
* @return self
*/
public static function getDebugPlugin($wireBodies = true, $stream = null)
{
if ($stream === null) {
if (defined('STDERR')) {
$stream = STDERR;
} else {
$stream = fopen('php://output', 'w');
}
}
return new self(new ClosureLogAdapter(function ($m) use ($stream) {
fwrite($stream, $m . PHP_EOL);
}), "# Request:\n{request}\n\n# Response:\n{response}\n\n# Errors: {curl_code} {curl_error}", $wireBodies);
}
public static function getSubscribedEvents()
{
return array(
'curl.callback.write' => array('onCurlWrite', 255),
'curl.callback.read' => array('onCurlRead', 255),
'request.before_send' => array('onRequestBeforeSend', 255),
'request.sent' => array('onRequestSent', 255)
);
}
/**
* Event triggered when curl data is read from a request
*
* @param Event $event
*/
public function onCurlRead(Event $event)
{
// Stream the request body to the log if the body is not repeatable
if ($wire = $event['request']->getParams()->get('request_wire')) {
$wire->write($event['read']);
}
}
/**
* Event triggered when curl data is written to a response
*
* @param Event $event
*/
public function onCurlWrite(Event $event)
{
// Stream the response body to the log if the body is not repeatable
if ($wire = $event['request']->getParams()->get('response_wire')) {
$wire->write($event['write']);
}
}
/**
* Called before a request is sent
*
* @param Event $event
*/
public function onRequestBeforeSend(Event $event)
{
if ($this->wireBodies) {
$request = $event['request'];
// Ensure that curl IO events are emitted
$request->getCurlOptions()->set('emit_io', true);
// We need to make special handling for content wiring and non-repeatable streams.
if ($request instanceof EntityEnclosingRequestInterface && $request->getBody()
&& (!$request->getBody()->isSeekable() || !$request->getBody()->isReadable())
) {
// The body of the request cannot be recalled so logging the body will require us to buffer it
$request->getParams()->set('request_wire', EntityBody::factory());
}
if (!$request->getResponseBody()->isRepeatable()) {
// The body of the response cannot be recalled so logging the body will require us to buffer it
$request->getParams()->set('response_wire', EntityBody::factory());
}
}
}
/**
* Triggers the actual log write when a request completes
*
* @param Event $event
*/
public function onRequestSent(Event $event)
{
$request = $event['request'];
$response = $event['response'];
$handle = $event['handle'];
if ($wire = $request->getParams()->get('request_wire')) {
$request = clone $request;
$request->setBody($wire);
}
if ($wire = $request->getParams()->get('response_wire')) {
$response = clone $response;
$response->setBody($wire);
}
// Send the log message to the adapter, adding a category and host
$priority = $response && $response->isError() ? LOG_ERR : LOG_DEBUG;
$message = $this->formatter->format($request, $response, $handle);
$this->logAdapter->log($message, $priority, array(
'request' => $request,
'response' => $response,
'handle' => $handle
));
}
}
|