| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- <?php
- namespace yzh52521\EasyHttp;
- use GuzzleHttp\Exception\RequestException;
- use GuzzleHttp\MessageFormatter;
- use GuzzleHttp\Promise;
- use Psr\Http\Message\RequestInterface;
- use Psr\Http\Message\ResponseInterface;
- use Psr\Log\LogLevel;
- use Psr\Log\LoggerInterface;
- use InvalidArgumentException;
- /**
- * Guzzle middleware which logs a request and its response.
- */
- class Logger
- {
- /**
- * @var \Psr\Log\LoggerInterface|callable
- */
- protected $logger;
- /**
- * @var \GuzzleHttp\MessageFormatter|callable
- */
- protected $formatter;
- /**
- * @var string|callable Constant or callable that accepts a Response.
- */
- protected $logLevel;
- /**
- * @var boolean Whether or not to log requests as they are made.
- */
- protected $logRequests;
- /**
- * Creates a callable middleware for logging requests and responses.
- *
- * @param LoggerInterface|callable $logger
- * @param string|callable Constant or callable that accepts a Response.
- */
- public function __construct($logger, $formatter = null)
- {
- // Use the setters to take care of type validation
- $this->setLogger($logger);
- $this->setFormatter($formatter ?: $this->getDefaultFormatter());
- }
- /**
- * Returns the default formatter;
- *
- * @return MessageFormatter
- */
- protected function getDefaultFormatter()
- {
- return new MessageFormatter();
- }
- /**
- * Sets whether requests should be logged before the response is received.
- *
- * @param boolean $logRequests
- */
- public function setRequestLoggingEnabled($logRequests = true)
- {
- $this->logRequests = (bool) $logRequests;
- }
- /**
- * Sets the logger, which can be a PSR-3 logger or a callable that accepts
- * a log level, message, and array context.
- *
- * @param LoggerInterface|callable $logger
- *
- * @throws InvalidArgumentException
- */
- public function setLogger($logger)
- {
- if ($logger instanceof LoggerInterface || is_callable($logger)) {
- $this->logger = $logger;
- } else {
- throw new InvalidArgumentException(
- "Logger has to be a Psr\Log\LoggerInterface or callable"
- );
- }
- }
- /**
- * Sets the formatter, which can be a MessageFormatter or callable that
- * accepts a request, response, and a reason if an error has occurred.
- *
- * @param MessageFormatter|callable $formatter
- *
- * @throws InvalidArgumentException
- */
- public function setFormatter($formatter)
- {
- if ($formatter instanceof MessageFormatter || is_callable($formatter)) {
- $this->formatter = $formatter;
- } else {
- throw new InvalidArgumentException(
- "Formatter has to be a \GuzzleHttp\MessageFormatter or callable"
- );
- }
- }
- /**
- * Sets the log level to use, which can be either a string or a callable
- * that accepts a response (which could be null). A log level could also
- * be null, which indicates that the default log level should be used.
- *
- * @param string|callable|null
- */
- public function setLogLevel($logLevel)
- {
- $this->logLevel = $logLevel;
- }
- /**
- * Logs a request and/or a response.
- *
- * @param RequestInterface $request
- * @param ResponseInterface|null $response
- * @param $reason
- * @return mixed
- */
- protected function log(
- RequestInterface $request,
- ResponseInterface $response = null,
- $reason = null
- ) {
- if ($reason instanceof RequestException) {
- $response = $reason->getResponse();
- }
- $level = $this->getLogLevel($response);
- $message = $this->getLogMessage($request, $response, $reason);
- $context = compact('request', 'response', 'reason');
- // Make sure that the content of the body is available again.
- if ($response) {
- $response->getBody()->seek(0);;
- }
- if (is_callable($this->logger)) {
- return call_user_func($this->logger, $level, $message, $context);
- }
- $this->logger->log($level, $message, $context);
- }
- /**
- * Formats a request and response as a log message.
- *
- * @param RequestInterface $request
- * @param ResponseInterface|null $response
- * @param mixed $reason
- *
- * @return string The formatted message.
- */
- protected function getLogMessage(
- RequestInterface $request,
- ResponseInterface $response = null,
- $reason = null
- ) {
- if ($this->formatter instanceof MessageFormatter) {
- return $this->formatter->format(
- $request,
- $response,
- $reason
- );
- }
- return call_user_func($this->formatter, $request, $response, $reason);
- }
- /**
- * Returns a log level for a given response.
- *
- * @param ResponseInterface $response The response being logged.
- *
- * @return string LogLevel
- */
- protected function getLogLevel(ResponseInterface $response = null)
- {
- if ( ! $this->logLevel) {
- return $this->getDefaultLogLevel($response);
- }
- if (is_callable($this->logLevel)) {
- return call_user_func($this->logLevel, $response);
- }
- return (string) $this->logLevel;
- }
- /**
- * Returns the default log level for a response.
- *
- * @param ResponseInterface $response
- *
- * @return string LogLevel
- */
- protected function getDefaultLogLevel(ResponseInterface $response = null) {
- if ($response && $response->getStatusCode() >= 300) {
- return LogLevel::NOTICE;
- }
- return LogLevel::INFO;
- }
- /**
- * Returns a function which is handled when a request was successful.
- *
- * @param RequestInterface $request
- *
- * @return \Closure
- */
- protected function onSuccess(RequestInterface $request)
- {
- return function ($response) use ($request) {
- $this->log($request, $response);
- return $response;
- };
- }
- /**
- * Returns a function which is handled when a request was rejected.
- *
- * @param RequestInterface $request
- *
- * @return \Closure
- */
- protected function onFailure(RequestInterface $request)
- {
- return function ($reason) use ($request) {
- // Only log a rejected request if it hasn't already been logged.
- if ( ! $this->logRequests) {
- $this->log($request, null, $reason);
- }
- return Promise\rejection_for($reason);
- };
- }
- /**
- * Called when the middleware is handled by the client.
- *
- * @param callable $handler
- *
- * @return \Closure
- */
- public function __invoke(callable $handler)
- {
- return function ($request, array $options) use ($handler) {
- // Only log requests if explicitly set to do so
- if ($this->logRequests) {
- $this->log($request);
- }
- return $handler($request, $options)->then(
- $this->onSuccess($request),
- $this->onFailure($request)
- );
- };
- }
- }
|