LogMiddleware   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
eloc 46
dl 0
loc 86
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A logRequest() 0 6 1
A __construct() 0 3 1
A handleFailure() 0 31 5
A __invoke() 0 11 2
A handleSuccess() 0 16 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the LetsEncrypt ACME client.
7
 *
8
 * @author    Ivanov Aleksandr <[email protected]>
9
 * @copyright 2019-2020
10
 * @license   https://github.com/misantron/letsencrypt-client/blob/master/LICENSE MIT License
11
 */
12
13
namespace LetsEncrypt\Logger;
14
15
use GuzzleHttp\Exception\RequestException;
16
use Psr\Http\Message\RequestInterface;
17
use Psr\Http\Message\ResponseInterface;
18
use Psr\Log\LogLevel;
19
20
use function GuzzleHttp\Promise\rejection_for;
21
22
final class LogMiddleware
23
{
24
    /**
25
     * @var Logger
26
     */
27
    private $logger;
28
29
    public function __construct(Logger $logger)
30
    {
31
        $this->logger = $logger;
32
    }
33
34
    public function __invoke(callable $handler): callable
35
    {
36
        return function (RequestInterface $request, array $options) use ($handler) {
37
            if ($this->logger->logRequestsOnly()) {
38
                $this->logRequest($request);
39
            }
40
41
            return $handler($request, $options)
42
                ->then(
43
                    $this->handleSuccess($request),
44
                    $this->handleFailure($request)
45
                );
46
        };
47
    }
48
49
    private function handleSuccess(RequestInterface $request): callable
50
    {
51
        return function (ResponseInterface $response) use ($request) {
52
            if ($this->logger->debugMode()) {
53
                $level = $this->logger->getLogLevel($response);
54
                $context = [
55
                    'method' => $request->getMethod(),
56
                    'url' => (string) $request->getUri(),
57
                    'status' => $response->getStatusCode(),
58
                    'headers' => json_encode($response->getHeaders(), JSON_PRETTY_PRINT),
59
                    'body' => $response->getBody()->getContents(),
60
                ];
61
                $this->logger->log($level, 'succeed request', $context);
62
            }
63
64
            return $response;
65
        };
66
    }
67
68
    private function handleFailure(RequestInterface $request): callable
69
    {
70
        return function (\Exception $reason) use ($request) {
71
            if ($this->logger->logErrorsOnly() || $this->logger->debugMode()) {
72
                if ($reason instanceof RequestException && $reason->hasResponse()) {
73
                    /** @var ResponseInterface $response */
74
                    $response = $reason->getResponse();
75
                    $context = [
76
                        'method' => $request->getMethod(),
77
                        'url' => (string) $request->getUri(),
78
                        'status' => $response->getStatusCode(),
79
                        'headers' => json_encode($response->getHeaders(), JSON_PRETTY_PRINT),
80
                        'body' => $response->getBody()->getContents(),
81
                    ];
82
                    $level = $this->logger->getLogLevel($response);
83
                    $this->logger->log($level, 'failed request', $context);
84
                } else {
85
                    $context = [
86
                        'method' => $request->getMethod(),
87
                        'url' => (string) $request->getUri(),
88
                        'reason' => [
89
                            'code' => $reason->getCode(),
90
                            'message' => $reason->getMessage(),
91
                            'trace' => $reason->getTrace(),
92
                        ],
93
                    ];
94
                    $this->logger->log(LogLevel::CRITICAL, 'invalid request', $context);
95
                }
96
            }
97
98
            return rejection_for($reason);
99
        };
100
    }
101
102
    private function logRequest(RequestInterface $request): void
103
    {
104
        $this->logger->log(LogLevel::INFO, 'request', [
105
            'method' => $request->getMethod(),
106
            'url' => (string) $request->getUri(),
107
            'headers' => $request->getHeaders(),
108
        ]);
109
    }
110
}
111