Giter Site home page Giter Site logo

gmponos / guzzle-log-middleware Goto Github PK

View Code? Open in Web Editor NEW
72.0 3.0 20.0 143 KB

A Guzzle middleware to log request and responses automatically

License: MIT License

PHP 100.00%
php log logger logger-middleware php7 guzzle guzzle-middleware guzzlehttp http psr-3 middleware rejection composer

guzzle-log-middleware's Introduction

Guzzle Log Middleware

codecov Total Downloads Build Status MIT licensed

This is a middleware for guzzle that will help you automatically log every request and response using a PSR-3 logger.

The middleware is functional with version 6 of Guzzle.

Install

Via Composer

$ composer require gmponos/guzzle_logger

Usage

Simple usage

use GuzzleLogMiddleware\LogMiddleware;
use GuzzleHttp\HandlerStack;

$logger = new Logger();  //A new PSR-3 Logger like Monolog
$stack = HandlerStack::create(); // will create a stack stack with middlewares of guzzle already pushed inside of it.
$stack->push(new LogMiddleware($logger));
$client = new GuzzleHttp\Client([
    'handler' => $stack,
]);

From now on each request and response you execute using $client object will be logged. By default the middleware logs every activity with level DEBUG.

Advanced initialization

The signature of the LogMiddleware class is the following:

\GuzzleLogMiddleware\LogMiddleware(
    \Psr\Log\LoggerInterface $logger, 
    \GuzzleLogMiddleware\Handler\HandlerInterface $handler = null, 
    bool $onFailureOnly = false, 
    bool $logStatistics = false
);
  • logger - The PSR-3 logger to use for logging.
  • handler - A HandlerInterface class that will be responsible for logging your request/response. Check Handlers sections.
  • onFailureOnly - By default the middleware is set to log every request and response. If you wish to log the HTTP messages only when guzzle returns a rejection set this as true or when an exception occurred. Guzzle returns a rejection when http_errors option is set to true.
  • logStatistics - If you set this option as true then the middleware will also log statistics about the HTTP transaction.

Handlers

In order to make the middleware more flexible we allow the developer to initialize it with a handler. A handler is the class that will be responsible for logging the HTTP message and it must implement a HandlerInterface.

As an example let's say that we create the following handler:

<?php
namespace GuzzleLogMiddleware\Handler;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\RequestInterface;
use GuzzleHttp\TransferStats;
use Psr\Log\LoggerInterface;

/** A simple handler that logs only requests */
final class SimpleHandler implements HandlerInterface
{
    public function log(
        LoggerInterface $logger,
        RequestInterface $request,
        ?ResponseInterface $response = null,
        ?\Throwable $exception = null,
        ?TransferStats $stats = null,
        array $options = []
    ): void {
        $logger->debug('Guzzle HTTP request: ' . \GuzzleHttp\Psr7\str($request));
        return;
    }
}

We can pass the handler above during construction of the middleware.

<?php
use GuzzleLogMiddleware\LogMiddleware;
use GuzzleHttp\HandlerStack;

$logger = new Logger();  //A new PSR-3 Logger like Monolog
$stack = HandlerStack::create(); // will create a stack stack with middlewares of guzzle already pushed inside of it.
$stack->push(new LogMiddleware($logger, new SimpleHandler()));
$client = new GuzzleHttp\Client([
    'handler' => $stack,
]);

From now on all Requests will be logged. Note that at the example above only requests are logged.

Important

If no handler is passed the middleware will initialize it's own handler. At the moment the default one is MultiRecordArrayHandler

MultiRecordArrayHandler

This is the default handler used from the middleware. This handler uses internally the FixedStrategy and logs all request and responses with level debug. This handler adds a separate log entry for each Request, Response, Exception or TransferStats. The information about each object are added as a context array to the log entry.

StringHandler

This handler uses internally the FixedStrategy and logs all request and responses with level debug. You can initialize this handler with a custom strategy. This handler adds a separate log entry for each Request, Response, Exception or TransferStats. The handler converts the objects to strings and the information about each object are added to the message of the log entry.

Log Level Strategies

Strategies are used to define the LogLevel that the handler will use to log each object.

FixedStrategy

You can use this strategy to log each HTTP Message with a specific level.

StatusCodeStrategy

You can use this strategy to log each HTTP Response with a specific level depending on the status code of the Response.

$strategy = new StatusCodeStrategy(
    LogLevel::INFO, // Default level used for requests or for responses that status code are not set with a different level.
    LogLevel::CRITICAL // Default level used for exceptions.
);
$strategy->setLevel(404, LogLevel::WARNING);
$multiRecordArrayHandler = new MultiRecordArrayHandler($strategy);

$logger = new Logger();  //A new PSR-3 Logger like Monolog
$stack = HandlerStack::create(); // will create a stack stack with middlewares of guzzle already pushed inside of it.
$stack->push(new LogMiddleware($logger, $multiRecordArrayHandler));
$client = new GuzzleHttp\Client([
    'handler' => $stack,
]);

Using options on each request

You can set on each request options about your log.

$client->get('/', [
    'log' => [
        'on_exception_only' => true,
        'statistics' => true,
    ]
]);
  • on_exception_only Do not log anything unless if the response status code is above the threshold.
  • statistics if the on_exception_only option/variable is true and this is also true the middleware will log statistics about the HTTP call.

Change log

Please see CHANGELOG for more information what has changed recently.

Testing

$ composer test

Credits

License

The MIT License (MIT). Please see License File for more information.

guzzle-log-middleware's People

Contributors

eduarguz avatar gmponos avatar grahamcampbell avatar joskfg avatar peter279k avatar skimmerle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

guzzle-log-middleware's Issues

Huge response truncates body

If a response is larger than 3499 characters, the logger truncates the log to 200 characters, but does not rewind the stream! So the first 200 characters are missing later when the response is received!

File: src/Handler/MultiRecordArrayHandler.php
Line: 152

    if ($stream->getSize() >= 3500) {
        return $stream->read(200) . ' (truncated...)';
    }

=> missing $stream->rewind()

Found in gmponos/guzzle_logger v1.0.0

Suggestion to update documentation

I have tried to use guzzle-log-middleware, roughly following the README,
however had problem with

Uncaught PHP Exception LogicException: "No handler has been specified"

When I have exchanged

$stack = new HandlerStack();
with
$stack = HandlerStack::create();

(Thanks to https://stackoverflow.com/a/32684940 )

my problem was solved.

Suggestion: maybe you might want to update README similarly.

Add support for PHP 8

When using PHP 8.0.3 image in Dockerfile, composer install command returns error gmponos / guzzle_logger requires php (^ 7.2). Please add support for PHP 8

` Step 16/29 : RUN set -eux; composer check-platform-reqs; composer install --ignore-platform-reqs --no-dev --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; composer clear-cache
---> Running in 4406700576f0

  • composer check-platform-reqs
    No vendor dir present, checking platform requirements from the lock file
    composer-plugin-api 2.0.0 success
    ext-ctype 8.0.3 success
    ext-dom 20031129 success
    ext-filter 8.0.3 success
    ext-intl 8.0.3 success
    ext-json 8.0.3 success
    ext-libxml 8.0.3 success
    ext-mbstring 8.0.3 success
    ext-openssl 8.0.3 success
    ext-pcre 8.0.3 success
    ext-pdo 8.0.3 success
    ext-pdo_mysql 8.0.3 success
    ext-phar 8.0.3 success
    ext-simplexml 8.0.3 success
    ext-tokenizer 8.0.3 success
    ext-xml 8.0.3 success
    ext-xmlwriter 8.0.3 success
    php 8.0.3 gmponos/guzzle_logger requires php (^7.2) failed
    ERROR: Service 'php' failed to build: The command '/bin/sh -c set -eux; composer check-platform-reqs; composer install --ignore-platform-reqs --no-dev --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; composer clear-cache' returned a non-zero code: 1 `

PHP_VERSION=8.0.3-fpm-alpine

guzzle_logger v2.2.0 incompatible with Guzzle >= 7.7.0

Using Guzzle 7.7.0 and gmponos/guzzle_logger 2.2.0, we recently ran into this error:

Error: Call to undefined function GuzzleHttp\Promise\rejection_for()

/project/vendor/gmponos/guzzle_logger/src/LogMiddleware.php:115
/project/vendor/guzzlehttp/promises/src/Promise.php:209
/project/vendor/guzzlehttp/promises/src/Promise.php:158
/project/vendor/guzzlehttp/promises/src/TaskQueue.php:52
/project/vendor/guzzlehttp/promises/src/Promise.php:251
/project/vendor/guzzlehttp/promises/src/Promise.php:227
/project/vendor/guzzlehttp/promises/src/Promise.php:272
/project/vendor/guzzlehttp/promises/src/Promise.php:229
/project/vendor/guzzlehttp/promises/src/Promise.php:69
/project/vendor/guzzlehttp/guzzle/src/Client.php:189
/project/vendor/guzzlehttp/guzzle/src/ClientTrait.php:44

I suspect it might have to do with Guzzle 7.7.0 now supporting guzzlehttp/promises v2, which removes all functions in favour of static methods (https://github.com/guzzle/promises/blob/2.0.0/CHANGELOG.md).

How we access MessageFormatter?

I want to customize the message.

If by hand, i normally do this.

Middleware::log(
app(LogManager::class)->channel('api-log'),
new MessageFormatter($messageFormat)
 )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.