├── .github └── FUNDING.yml ├── composer.json ├── phpunit.xml └── src ├── ExceptionMiddleware.php ├── Profiler.php └── Support └── Laravel └── ServiceProvider.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [hannesvdvreken, barryvdh] 2 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hannesvdvreken/guzzle-debugbar", 3 | "description": "A Guzzle middleware that logs requests to debugbar's timeline", 4 | "keywords": [ 5 | "Debugbar", "http", "log", "Guzzle", "middleware", "profiling", "profiler", "PHP" 6 | ], 7 | "type": "library", 8 | "license": "MIT", 9 | "authors": [ 10 | { 11 | "name": "Hannes Van De Vreken", 12 | "email": "vandevreken.hannes@gmail.com" 13 | }, 14 | { 15 | "name": "Barry vd. Heuvel", 16 | "email": "barryvdh@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=7.2", 21 | "hannesvdvreken/guzzle-profiler": "^2", 22 | "php-debugbar/php-debugbar": "^2" 23 | }, 24 | "require-dev": { 25 | "illuminate/support": ">=6", 26 | "phpunit/phpunit": "^8.2.3", 27 | "friendsofphp/php-cs-fixer": "^2.2.20" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "GuzzleHttp\\Profiling\\Debugbar\\": "src/" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "GuzzleHttp\\Profiling\\Debugbar\\Unit\\": "tests/unit/" 37 | } 38 | }, 39 | "funding": [ 40 | { 41 | "type": "github", 42 | "url": "https://github.com/sponsors/hannesvdvreken" 43 | }, 44 | { 45 | "type": "github", 46 | "url": "https://github.com/sponsors/barryvdh" 47 | } 48 | ], 49 | "config": { 50 | "sort-packages": true 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/unit/ 15 | 16 | 17 | 18 | 19 | src/ 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/ExceptionMiddleware.php: -------------------------------------------------------------------------------- 1 | collector = $collector; 26 | } 27 | 28 | /** 29 | * @param callable $handler 30 | * 31 | * @return callable 32 | */ 33 | public function __invoke(callable $handler): callable 34 | { 35 | return function(RequestInterface $request, array $options) use ($handler): PromiseInterface { 36 | return $handler($request, $options) 37 | ->then(function(ResponseInterface $response) { 38 | return $response; 39 | }, function(ClientExceptionInterface $exception) { 40 | $this->collector->addException($exception); 41 | 42 | throw $exception; 43 | }); 44 | }; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Profiler.php: -------------------------------------------------------------------------------- 1 | timeline = $timeline; 40 | } 41 | 42 | /** 43 | * @param float $start 44 | * @param float $end 45 | * @param \Psr\Http\Message\RequestInterface $request 46 | * @param \Psr\Http\Message\ResponseInterface $response 47 | */ 48 | public function add(float $start, float $end, RequestInterface $request, ResponseInterface $response = null): void 49 | { 50 | $description = $this->describe($request, $response); 51 | $params = $this->getParameters($request, $response); 52 | 53 | $this->timeline->addMeasure($description, $start, $end, $params, 'guzzle'); 54 | } 55 | 56 | /** 57 | * Get context fields to add to the time-line entry. 58 | * 59 | * @param \Psr\Http\Message\RequestInterface $request 60 | * @param \Psr\Http\Message\ResponseInterface $response 61 | * 62 | * @return array 63 | */ 64 | protected function getParameters(RequestInterface $request, ResponseInterface $response = null): array 65 | { 66 | $params = []; 67 | $result = ''; 68 | 69 | $keys = array_intersect($this->context, $this->availableParameters); 70 | 71 | foreach ($keys as $key) { 72 | switch ($key) { 73 | case 'method': 74 | $result = $request->getMethod(); 75 | break; 76 | case 'url': 77 | $result = $request->getUri()->__toString(); 78 | break; 79 | case 'request_version': 80 | $result = $request->getProtocolVersion(); 81 | break; 82 | case 'response_version': 83 | $result = $response ? $response->getProtocolVersion() : 'NULL'; 84 | break; 85 | case 'host': 86 | $result = $request->getUri()->getHost(); 87 | break; 88 | case 'hostname': 89 | $result = gethostname(); 90 | break; 91 | case 'status_code': 92 | $result = $response ? $response->getStatusCode() : 'NULL'; 93 | break; 94 | case 'phrase': 95 | $result = $response ? $response->getReasonPhrase() : 'NULL'; 96 | break; 97 | } 98 | 99 | $params[$key] = (string) $result ?: ''; 100 | } 101 | 102 | return $params; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Support/Laravel/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->bind(PsrClientInterface::class, function(): PsrClientInterface { 39 | // Guzzle client 40 | return new Client(['handler' => $this->app->make(HandlerStack::class)]); 41 | }); 42 | 43 | $this->app->alias(PsrClientInterface::class, Client::class); 44 | $this->app->alias(PsrClientInterface::class, ClientInterface::class); 45 | 46 | // Bind if needed. 47 | $this->app->bind(HandlerStack::class, function(): HandlerStack { 48 | return HandlerStack::create(); 49 | }); 50 | 51 | // If resolved, by this SP or another, add some layers. 52 | $this->app->resolving(HandlerStack::class, function(HandlerStack $stack): void { 53 | // We cannot log with debugbar from the CLI 54 | if ($this->app->runningInConsole()) { 55 | return; 56 | } 57 | 58 | /** @var \DebugBar\DebugBar $debugBar */ 59 | $debugBar = $this->app->make('debugbar'); 60 | 61 | $stack->push(new Middleware(new Profiler($timeline = $debugBar->getCollector('time')))); 62 | $stack->unshift(new ExceptionMiddleware($debugBar->getCollector('exceptions'))); 63 | 64 | /** @var \GuzzleHttp\MessageFormatter $formatter */ 65 | $formatter = $this->app->make(MessageFormatter::class); 66 | $stack->unshift(GuzzleMiddleware::log($debugBar->getCollector('messages'), $formatter)); 67 | 68 | // Also log to the default PSR logger. 69 | if ($this->app->bound(LoggerInterface::class)) { 70 | $logger = $this->app->make(LoggerInterface::class); 71 | 72 | // Don't log to the same logger twice. 73 | if ($logger === $debugBar->getCollector('messages')) { 74 | return; 75 | } 76 | 77 | // Push the middleware on the stack. 78 | $stack->unshift(GuzzleMiddleware::log($logger, $formatter)); 79 | } 80 | }); 81 | } 82 | } 83 | --------------------------------------------------------------------------------