Skip to content

Commit 37cd883

Browse files
committed
For hyperf 3.0
1 parent f8f0252 commit 37cd883

11 files changed

+93
-397
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Changelog
2+
3+
## 3.0.0 (2023-09-11)
4+
5+
* Support Hyperf 3.0 only.
6+
* Remove Logger class, uses instance of `Hyperf` to logging request log.
7+
* Remove deprecated logics.
8+
* Remove slow requests time behaviors.

README.md

-18
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,6 @@ To allow HTTP Logger in your application, add the `HttpLoggerMiddleware` middlew
2727
],
2828
```
2929

30-
Also, to allow HTTP Logger for exception responses, you need add the `HttpLoggerExceptionHandler` handler at the bottom of the property of `config/autoload/exceptions.php` file:
31-
32-
```php
33-
'handler' => [
34-
'http' => [
35-
...
36-
Gokure\HttpLogger\HttpLoggerExceptionHandler::class,
37-
],
38-
],
39-
```
40-
41-
> **Note:** No response logged, if `$this->stopPropagation()` is used in the previous exception handlers.
42-
43-
## TODO
44-
45-
- [ ] To filter secret body of requests and responses.
46-
- [ ] Add test cases.
47-
4830
## License
4931

5032
Released under the MIT License, see [LICENSE](LICENSE).

composer.json

+9-15
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,16 @@
1111
}
1212
],
1313
"require": {
14-
"php": ">= 7.2",
15-
"ext-swoole": ">= 4.4",
16-
"psr/log": "^1.0",
17-
"psr/container": "^1.0",
18-
"hyperf/contract": "^1.0|^2.0",
19-
"hyperf/di": "^1.0|^2.0",
20-
"hyperf/http-server": "^1.0|^2.0",
21-
"hyperf/utils": "^1.0|^2.0",
22-
"monolog/monolog": "^2.0"
14+
"php": ">= 8.0",
15+
"hyperf/di": "~3.0.0",
16+
"hyperf/http-server": "~3.0.0",
17+
"hyperf/logger": "~3.0.0",
18+
"monolog/monolog": "^2.7|^3.1"
2319
},
2420
"require-dev": {
25-
"mockery/mockery": "^1.0",
26-
"phpunit/phpunit": "^7.0.0",
27-
"hyperf/testing": "^1.0|^2.0",
28-
"roave/security-advisories": "dev-master",
29-
"swoole/ide-helper": "^4.5"
21+
"mockery/mockery": "^1.4",
22+
"phpunit/phpunit": "^9.5",
23+
"hyperf/testing": "~3.0.0"
3024
},
3125
"autoload": {
3226
"psr-4": {
@@ -35,7 +29,7 @@
3529
},
3630
"extra": {
3731
"branch-alias": {
38-
"dev-master": "1.0-dev"
32+
"dev-master": "3.0-dev"
3933
},
4034
"hyperf": {
4135
"config": "Gokure\\HttpLogger\\ConfigProvider"

publish/http_logger.php

+13-18
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,33 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
return [
46
/**
57
* Matches the log request method. `['*']` allows all methods.
68
*/
7-
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
9+
'allowed_methods' => ['*'],
810

911
/**
1012
* Matches the log context of request method. `['*']` allows all methods.
1113
*/
1214
'allowed_context_methods' => ['POST', 'PUT', 'PATCH', 'DELETE'],
1315

1416
/**
15-
* Sets the slow requests when > 0
17+
* Determine bypass logging when the true returned.
18+
* For example, you can ignore logging for given user agent.
19+
*
20+
* function ($response, $request) {
21+
* return $request->getHeaderLine('user-agent') === 'SLBHealthCheck';
22+
* }
1623
*/
17-
'long_request_time' => (float)env('HTTP_LOGGER_LONG_REQUEST_TIME', 3.0),
24+
'bypass_function' => function ($response, $request) {},
1825

1926
/**
20-
* Sets the logger instance, same as the logger.php file in hyperf.
27+
* Sets the logger instance.
2128
*/
2229
'logger' => [
23-
'handler' => [
24-
'class' => Monolog\Handler\StreamHandler::class,
25-
'constructor' => [
26-
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
27-
],
28-
],
29-
'formatter' => [
30-
'class' => Monolog\Formatter\LineFormatter::class,
31-
'constructor' => [
32-
'format' => null,
33-
'dateFormat' => 'Y-m-d H:i:s',
34-
'allowInlineLineBreaks' => false,
35-
],
36-
],
30+
'name' => 'hyperf',
31+
'group' => 'default',
3732
],
3833
];

src/HttpLogger.php

+54-61
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,30 @@
55
namespace Gokure\HttpLogger;
66

77
use Hyperf\Contract\ConfigInterface;
8-
use Hyperf\Utils\Context;
9-
use Psr\Container\ContainerInterface;
8+
use Hyperf\Logger\LoggerFactory;
9+
use Monolog\Level;
1010
use Psr\Http\Message\ResponseInterface;
1111
use Psr\Http\Message\ServerRequestInterface;
12+
use Psr\Log\LoggerInterface;
13+
use function \Hyperf\Collection\collect;
1214

1315
class HttpLogger
1416
{
15-
protected const HYPERF_START = __CLASS__ . '.HYPERF_START';
17+
protected LoggerInterface $logger;
1618

17-
/**
18-
* @var ContainerInterface
19-
*/
20-
protected $container;
19+
protected array $options;
2120

22-
/**
23-
* @var array
24-
*/
25-
protected $options;
26-
27-
public function __construct(ContainerInterface $container)
28-
{
29-
$this->container = $container;
30-
$options = $this->container->get(ConfigInterface::class)->get('http_logger', []);
31-
$this->options = $this->normalizeOptions($options);
32-
}
33-
34-
public function setUp(): void
21+
public function __construct(LoggerFactory $factory, ConfigInterface $config)
3522
{
36-
Context::set(static::HYPERF_START, microtime(true));
23+
$this->options = $this->normalizeOptions($config->get('http_logger', []));
24+
$name = $this->options['logger']['name'] ?? 'hyperf';
25+
$group = $this->options['logger']['group'] ?? 'default';
26+
$this->logger = $factory->get($name, $group);
3727
}
3828

39-
public function record(ResponseInterface $response, ServerRequestInterface $request, $level = Logger::INFO): void
29+
public function record(\Throwable|ResponseInterface $response, ServerRequestInterface $request): void
4030
{
41-
if (!$this->shouldRecord($response, $request)) {
31+
if (! $this->shouldRecord($response, $request)) {
4232
return;
4333
}
4434

@@ -58,43 +48,56 @@ public function record(ResponseInterface $response, ServerRequestInterface $requ
5848
})->toArray(),
5949
]);
6050

61-
$context['response'] = array_filter([
62-
'body' => (string)$response->getBody(),
63-
]);
51+
if ($response instanceof \Throwable) {
52+
$context['exception'] = [
53+
'message' => $response->getMessage(),
54+
'trace' => $response->getTraceAsString(),
55+
];
56+
} else {
57+
$context['response'] = array_filter([
58+
'body' => (string)$response->getBody(),
59+
]);
60+
}
6461
}
6562

66-
$requestTime = microtime(true) - Context::get(static::HYPERF_START, microtime(true));
67-
Context::destroy(static::HYPERF_START);
63+
$server = $request->getServerParams();
64+
if (isset($server['request_time_float'])) {
65+
$startTime = $server['request_time_float'];
66+
$executeTime = number_format(microtime(true) - $startTime, 3);
67+
} else {
68+
$executeTime = '-';
69+
}
6870

6971
// "GET /path HTTP/1.1" 200 0.026 "User-Agent"
7072
$message = sprintf('"%s %s HTTP/%s" %s %s "%s"',
7173
$request->getMethod(),
7274
$request->getRequestTarget(),
7375
$request->getProtocolVersion(),
74-
$response->getStatusCode(),
75-
number_format($requestTime, 3),
76-
$request->getHeaderLine('User-Agent')
76+
$response instanceof ResponseInterface ? $response->getStatusCode() : '-',
77+
$executeTime,
78+
$request->getHeaderLine('user-agent')
7779
);
7880

79-
if ($this->options['long_request_time'] > 0 && $requestTime >= $this->options['long_request_time']) {
80-
$logger = $this->container->get(LoggerFactory::class)->get('http-slow');
81-
} else {
82-
$logger = $this->container->get(LoggerFactory::class)->get('http');
83-
}
84-
85-
$logger->log($level, $message, $context);
81+
$level = $response instanceof \Throwable ? Level::Error : Level::Info;
82+
$this->logger->log($level, $message, $context);
8683
}
8784

88-
protected function shouldRecord(ResponseInterface $response, ServerRequestInterface $request): bool
85+
protected function shouldRecord(\Throwable|ResponseInterface $response, ServerRequestInterface $request): bool
8986
{
90-
return !$this->isSuccessful($response) ||
91-
$this->options['allowed_methods'] === true ||
92-
in_array(strtoupper($request->getMethod()), $this->options['allowed_methods'], true);
87+
return $response instanceof \Throwable ||
88+
! $this->isSuccessful($response) ||
89+
(
90+
(
91+
$this->options['allowed_methods'] === true ||
92+
in_array(strtoupper($request->getMethod()), $this->options['allowed_methods'], true)
93+
) && $this->options['bypass_function']($response, $request) !== true
94+
);
9395
}
9496

95-
protected function shouldRecordContext(ResponseInterface $response, ServerRequestInterface $request): bool
97+
protected function shouldRecordContext(\Throwable|ResponseInterface $response, ServerRequestInterface $request): bool
9698
{
97-
return !$this->isSuccessful($response) ||
99+
return $response instanceof \Throwable ||
100+
! $this->isSuccessful($response) ||
98101
$this->options['allowed_context_methods'] === true ||
99102
in_array(strtoupper($request->getMethod()), $this->options['allowed_context_methods'], true);
100103
}
@@ -109,28 +112,18 @@ protected function normalizeOptions(array $options = []): array
109112
$options += [
110113
'allowed_methods' => ['*'],
111114
'allowed_context_methods' => ['POST', 'PUT', 'PATCH', 'DELETE'],
112-
'slow_request_log' => false,
113-
'long_request_time' => 3.0,
114115
'logger' => [
115-
'handler' => [
116-
'class' => \Monolog\Handler\StreamHandler::class,
117-
'constructor' => [
118-
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
119-
],
120-
],
121-
'formatter' => [
122-
'class' => \Monolog\Formatter\LineFormatter::class,
123-
'constructor' => [
124-
'format' => null,
125-
'dateFormat' => 'Y-m-d H:i:s',
126-
'allowInlineLineBreaks' => false,
127-
],
128-
],
116+
'name' => 'hyperf',
117+
'group' => 'default',
129118
],
130119
];
131120

121+
if (! isset($options['bypass_function'])) {
122+
$options['bypass_function'] = function () {};
123+
}
124+
132125
foreach (['allowed_methods', 'allowed_context_methods'] as $key) {
133-
if (!is_array($options[$key])) {
126+
if (! is_array($options[$key])) {
134127
throw new \RuntimeException('Http Logger config `' . $key . '` should be an array.');
135128
}
136129
}

src/HttpLoggerExceptionHandler.php

-39
This file was deleted.

src/HttpLoggerMiddleware.php

+9-12
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,19 @@
1111

1212
class HttpLoggerMiddleware implements MiddlewareInterface
1313
{
14-
/**
15-
* @var HttpLogger
16-
*/
17-
protected $httpLogger;
18-
19-
public function __construct(HttpLogger $httpLogger)
14+
public function __construct(protected HttpLogger $logger)
2015
{
21-
$this->httpLogger = $httpLogger;
2216
}
2317

2418
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
2519
{
26-
$this->httpLogger->setUp();
27-
$response = $handler->handle($request);
28-
$this->httpLogger->record($response, $request);
29-
30-
return $response;
20+
try {
21+
$response = $handler->handle($request);
22+
$this->logger->record($response, $request);
23+
return $response;
24+
} catch (\Throwable $e) {
25+
$this->logger->record($e, $request);
26+
throw $e;
27+
}
3128
}
3229
}

src/Logger.php

-12
This file was deleted.

0 commit comments

Comments
 (0)