Skip to content

Commit 6c2fa70

Browse files
committed
Merge branch 'master' into 6.x
2 parents 813d9fa + bc6a682 commit 6c2fa70

31 files changed

+926
-188
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
}],
1414
"require": {
1515
"php": "^7.2",
16+
"ext-json": "*",
1617
"illuminate/support": "^6.0",
1718
"illuminate/console": "^6.0",
1819
"illuminated/helper-functions": "^6.0",

integrations/guzzle.php

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
<?php
22

3-
use Psr\Log\LoggerInterface;
4-
use Psr\Http\Message\RequestInterface;
3+
use function GuzzleHttp\Promise\rejection_for;
54
use Illuminated\Console\Exceptions\RuntimeException;
5+
use Psr\Http\Message\RequestInterface;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Log\LoggerInterface;
68

79
if (!function_exists('iclogger_guzzle_middleware')) {
8-
function iclogger_guzzle_middleware(LoggerInterface $log, $type = 'raw', callable $shouldLogRequest = null, callable $shouldLogResponse = null)
10+
/**
11+
* Create a Guzzle middleware to provide logging of Guzzle requests/responses.
12+
*
13+
* @see https://github.com/dmitry-ivanov/laravel-console-logger#guzzle-6-integration
14+
* @see http://docs.guzzlephp.org/en/stable/handlers-and-middleware.html
15+
*
16+
* @param \Psr\Log\LoggerInterface $logger
17+
* @param string $type
18+
* @param callable|null $shouldLogRequest
19+
* @param callable|null $shouldLogResponse
20+
* @return \Closure
21+
*/
22+
function iclogger_guzzle_middleware(LoggerInterface $logger, string $type = 'raw', callable $shouldLogRequest = null, callable $shouldLogResponse = null)
923
{
10-
return function (callable $handler) use ($log, $type, $shouldLogRequest, $shouldLogResponse) {
11-
return function (RequestInterface $request, array $options) use ($handler, $log, $type, $shouldLogRequest, $shouldLogResponse) {
24+
return function (callable $handler) use ($logger, $type, $shouldLogRequest, $shouldLogResponse) {
25+
return function (RequestInterface $request, array $options) use ($handler, $logger, $type, $shouldLogRequest, $shouldLogResponse) {
26+
// Gather information about the request
1227
$method = (string) $request->getMethod();
1328
$uri = (string) $request->getUri();
1429
$body = (string) $request->getBody();
1530

16-
if (empty($body)) {
31+
// Log the request with a proper message and context
32+
if (isset($shouldLogRequest) && !$shouldLogRequest($request)) {
33+
$message = "[{$method}] Calling `{$uri}`, body is not shown, according to the custom logic.";
34+
$context = [];
35+
} elseif (empty($body)) {
1736
$message = "[{$method}] Calling `{$uri}`.";
1837
$context = [];
1938
} else {
@@ -30,55 +49,46 @@ function iclogger_guzzle_middleware(LoggerInterface $log, $type = 'raw', callabl
3049
break;
3150
}
3251
}
52+
$logger->info($message, $context);
3353

34-
if (!empty($shouldLogRequest)) {
35-
$shouldLogRequest = call_user_func($shouldLogRequest, $request);
36-
if (!$shouldLogRequest) {
37-
$message = "[{$method}] Calling `{$uri}`, body is not shown, according to the custom logic.";
38-
$context = [];
39-
}
40-
}
41-
42-
$log->info($message, $context);
43-
54+
// Using another callback to log the response
4455
return $handler($request, $options)->then(
45-
function ($response) use ($request, $log, $type, $shouldLogResponse) {
56+
function (ResponseInterface $response) use ($request, $logger, $type, $shouldLogResponse) {
57+
// Gather information about the response
4658
$body = (string) $response->getBody();
4759
$code = $response->getStatusCode();
4860

49-
$message = "[{$code}] Response:";
50-
switch ($type) {
51-
case 'json':
52-
$context = is_json($body, true);
53-
if (empty($context)) {
54-
throw new RuntimeException('Bad response, json expected.', ['response' => $body]);
55-
}
56-
break;
57-
58-
case 'raw':
59-
default:
60-
$message .= "\n{$body}";
61-
$context = [];
62-
break;
63-
}
64-
if (!empty($context)) {
65-
$response->iclParsedBody = $context;
66-
}
61+
// Log the response with a proper message and context
62+
if (isset($shouldLogResponse) && !$shouldLogResponse($request, $response)) {
63+
$message = "[{$code}] Response is not shown, according to the custom logic.";
64+
$context = [];
65+
} else {
66+
$message = "[{$code}] Response:";
67+
switch ($type) {
68+
case 'json':
69+
$context = is_json($body, true);
70+
if (empty($context)) {
71+
throw new RuntimeException('Bad response, JSON expected.', ['response' => $body]);
72+
}
73+
break;
6774

68-
if (!empty($shouldLogResponse)) {
69-
$shouldLogResponse = call_user_func($shouldLogResponse, $request, $response);
70-
if (!$shouldLogResponse) {
71-
$message = "[{$code}] Response is not shown, according to the custom logic.";
72-
$context = [];
75+
case 'raw':
76+
default:
77+
$message .= "\n{$body}";
78+
$context = [];
79+
break;
80+
}
81+
// Save the parsed body of response, so that it could be re-used instead of double decoding
82+
if (!empty($context)) {
83+
$response->iclParsedBody = $context;
7384
}
7485
}
75-
76-
$log->info($message, $context);
86+
$logger->info($message, $context);
7787

7888
return $response;
7989
},
8090
function ($reason) {
81-
return \GuzzleHttp\Promise\rejection_for($reason);
91+
return rejection_for($reason);
8292
}
8393
);
8494
};

src/Exceptions/ExceptionHandler.php

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,73 @@
33
namespace Illuminated\Console\Exceptions;
44

55
use Exception;
6-
use Psr\Log\LoggerInterface;
76
use Illuminate\Foundation\Exceptions\Handler;
7+
use Psr\Log\LoggerInterface;
88

99
class ExceptionHandler extends Handler
1010
{
11+
/**
12+
* The logger instance.
13+
*
14+
* @var \Psr\Log\LoggerInterface
15+
*/
1116
private $logger;
17+
18+
/**
19+
* Time when execution started.
20+
*
21+
* @var float
22+
*/
1223
private $timeStarted;
24+
25+
/**
26+
* Time when execution finished.
27+
*
28+
* @var float
29+
*/
1330
private $timeFinished;
14-
protected $reservedMemory;
1531

16-
public function setLogger(LoggerInterface $logger)
17-
{
18-
$this->logger = $logger;
19-
}
32+
/**
33+
* Reserved memory for the shutdown execution.
34+
*
35+
* @see https://github.com/dmitry-ivanov/laravel-console-logger/issues/4
36+
*
37+
* @var string
38+
*/
39+
protected $reservedMemory;
2040

41+
/**
42+
* Initialize the exception handler.
43+
*
44+
* @param \Psr\Log\LoggerInterface $logger
45+
* @return void
46+
*/
2147
public function initialize(LoggerInterface $logger)
2248
{
2349
$this->setLogger($logger);
2450
$this->registerShutdownFunction();
2551
}
2652

53+
/**
54+
* Set the logger.
55+
*
56+
* @param \Psr\Log\LoggerInterface $logger
57+
* @return void
58+
*/
59+
public function setLogger(LoggerInterface $logger)
60+
{
61+
$this->logger = $logger;
62+
}
63+
64+
/**
65+
* Report or log an exception.
66+
*
67+
* Note that this method doesn't decorate, but overwrite the parent method:
68+
* @see https://github.com/dmitry-ivanov/laravel-console-logger/pull/11
69+
*
70+
* @param \Exception $e
71+
* @return void
72+
*/
2773
public function report(Exception $e)
2874
{
2975
$context = [
@@ -34,15 +80,35 @@ public function report(Exception $e)
3480
];
3581

3682
if ($e instanceof RuntimeException) {
37-
$eContext = $e->getContext();
38-
if (!empty($eContext)) {
39-
$context['context'] = $eContext;
83+
$exceptionContext = $e->getContext();
84+
if (!empty($exceptionContext)) {
85+
$context['context'] = $exceptionContext;
4086
}
4187
}
4288

4389
$this->logger->error($e->getMessage(), $context);
90+
91+
$this->addSentrySupport($e);
92+
}
93+
94+
/**
95+
* Add Sentry support.
96+
*
97+
* @param \Exception $e
98+
* @return void
99+
*/
100+
private function addSentrySupport(Exception $e)
101+
{
102+
if (app()->bound('sentry') && $this->shouldReport($e)) {
103+
app('sentry')->captureException($e);
104+
}
44105
}
45106

107+
/**
108+
* Register the shutdown function.
109+
*
110+
* @return void
111+
*/
46112
private function registerShutdownFunction()
47113
{
48114
$this->timeStarted = microtime(true);
@@ -51,6 +117,11 @@ private function registerShutdownFunction()
51117
register_shutdown_function([$this, 'onShutdown']);
52118
}
53119

120+
/**
121+
* Callback for the shutdown function.
122+
*
123+
* @return void
124+
*/
54125
public function onShutdown()
55126
{
56127
$this->reservedMemory = null;

src/Exceptions/RuntimeException.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,34 @@
77

88
class RuntimeException extends SymfonyRuntimeException
99
{
10+
/**
11+
* The context.
12+
*
13+
* @var array
14+
*/
1015
private $context;
1116

12-
public function __construct($message = '', array $context = [], $code = 0, Exception $previous = null)
17+
/**
18+
* Create a new instance of the exception.
19+
*
20+
* @param string $message
21+
* @param array $context
22+
* @param int $code
23+
* @param \Exception|null $previous
24+
* @return void
25+
*/
26+
public function __construct(string $message = '', array $context = [], int $code = 0, Exception $previous = null)
1327
{
1428
$this->context = $context;
1529

1630
parent::__construct($message, $code, $previous);
1731
}
1832

33+
/**
34+
* Get the context.
35+
*
36+
* @return array
37+
*/
1938
public function getContext()
2039
{
2140
return $this->context;

0 commit comments

Comments
 (0)