Overview

Namespaces

  • Contrib
    • Bundle
      • CoverallsBundle
        • Console
        • Entity
      • CoverallsV1Bundle
        • Api
        • Collector
        • Command
        • Config
        • Entity
          • Git
    • Component
      • File
      • Log
      • System
        • Git
  • Guzzle
    • Batch
      • Exception
    • Cache
    • Common
      • Exception
    • Http
      • Curl
      • Exception
      • Message
      • QueryAggregator
    • Inflection
    • Iterator
    • Log
    • Parser
      • Cookie
      • Message
      • UriTemplate
      • Url
    • Plugin
      • Async
      • Backoff
      • Cache
      • Cookie
        • CookieJar
        • Exception
      • CurlAuth
      • ErrorResponse
        • Exception
      • History
      • Log
      • Md5
      • Mock
      • Oauth
    • Service
      • Builder
      • Command
        • Factory
        • LocationVisitor
          • Request
          • Response
      • Description
      • Exception
      • Resource
    • Stream
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Config
        • Definition
          • Builder
          • Exception
        • Exception
        • Loader
        • Resource
        • Util
      • Console
        • Command
        • Formatter
        • Helper
        • Input
        • Output
        • Tester
      • EventDispatcher
        • Debug
      • Finder
        • Adapter
        • Comparator
        • Exception
        • Expression
        • Iterator
        • Shell
      • Stopwatch
      • Yaml
        • Exception

Classes

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