mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-11-29 18:27:44 +08:00
Adds RequestTraceListener
for hyperf/tracer
(#6062)
This commit is contained in:
parent
1dd9b51881
commit
683e45e556
@ -1,5 +1,9 @@
|
||||
# v3.0.36 - TBD
|
||||
|
||||
# Added
|
||||
|
||||
- [#6062](https://github.com/hyperf/hyperf/pull/6057) Added `RequestTraceListener` for `hyperf/tracer`.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#6117](https://github.com/hyperf/hyperf/pull/6117) Fixed bug that grpc client cannot able to be reused.
|
||||
|
@ -194,9 +194,12 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
### Configure middleware
|
||||
### Configure middleware or listener
|
||||
|
||||
After configuring the driver, you need to configure the middleware or request cycle event listener to collect information to enable the collection function.
|
||||
|
||||
- Add middleware
|
||||
|
||||
After configuring the driver, you need to configure the middleware to enable the collection function to collect information.
|
||||
Open the `config/autoload/middlewares.php` file and enable the middleware on the `http` node.
|
||||
|
||||
```php
|
||||
@ -205,9 +208,23 @@ Open the `config/autoload/middlewares.php` file and enable the middleware on the
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'http' => [
|
||||
\Hyperf\Tracer\Middleware\TraceMiddleware::class,
|
||||
],
|
||||
'http' => [
|
||||
\Hyperf\Tracer\Middleware\TraceMiddleware::class,
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
- or add a listener
|
||||
|
||||
Open the `config/autoload/listeners.php` file and add the listener.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
\Hyperf\Tracer\Listener\RequestTraceListener::class,
|
||||
];
|
||||
```
|
||||
|
||||
|
@ -194,9 +194,12 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
### 配置中间件
|
||||
### 配置中间件或监听器
|
||||
|
||||
配置完驱动之后,采集信息还需要配置一下中间件或请求周期事件监听器才能启用采集功能。
|
||||
|
||||
- 添加中间件
|
||||
|
||||
配置完驱动之后,采集信息还需要配置一下中间件才能启用采集功能。
|
||||
打开 `config/autoload/middlewares.php` 文件,在 `http` 节点启用中间件。
|
||||
|
||||
```php
|
||||
@ -211,6 +214,20 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
- 或者添加监听器
|
||||
|
||||
打开 `config/autoload/listeners.php` 文件,添加监听器。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
\Hyperf\Tracer\Listener\RequestTraceListener::class,
|
||||
];
|
||||
```
|
||||
|
||||
### 配置 Span tag
|
||||
|
||||
对于一些 Hyperf 自动收集追踪信息的 Span Tag 名称,可以通过更改 Span Tag 配置来更改对应的名称,只需在配置文件 `config/autolaod/opentracing.php` 内增加 `tags` 配置即可,参考配置如下。如配置项存在,则以配置项的值为准,如配置项不存在,则以组件的默认值为准。
|
||||
|
@ -194,10 +194,13 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
### 配置中間件
|
||||
### 配置中間件或監聽器
|
||||
|
||||
配置完驅動之後,採集信息還需要配置一下中間件才能啓用採集功能。
|
||||
打開 `config/autoload/middlewares.php` 文件,在 `http` 節點啓用中間件。
|
||||
配置完驅動之後,採集信息還需要配置一下中間件或請求週期事件監聽器才能啟用採集功能。
|
||||
|
||||
- 添加中間件
|
||||
|
||||
打開 `config/autoload/middlewares.php` 文件,在 `http` 節點啟用中間件。
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -211,6 +214,20 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
- 或者添加監聽器
|
||||
|
||||
打開 `config/autoload/listeners.php` 文件,添加監聽器。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
\Hyperf\Tracer\Listener\RequestTraceListener::class,
|
||||
];
|
||||
```
|
||||
|
||||
### 配置 Span tag
|
||||
|
||||
對於一些 Hyperf 自動收集追蹤信息的 Span Tag 名稱,可以通過更改 Span Tag 配置來更改對應的名稱,只需在配置文件 `config/autolaod/opentracing.php` 內增加 `tags` 配置即可,參考配置如下。如配置項存在,則以配置項的值為準,如配置項不存在,則以組件的默認值為準。
|
||||
|
@ -194,9 +194,12 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
### 配置中介軟體
|
||||
### 配置中介軟體或監聽器
|
||||
|
||||
配置完驅動之後,採集資訊還需要配置一下中介軟體或請求週期事件監聽器才能啟用採集功能。
|
||||
|
||||
- 新增中介軟體
|
||||
|
||||
配置完驅動之後,採集資訊還需要配置一下中介軟體才能啟用採集功能。
|
||||
開啟 `config/autoload/middlewares.php` 檔案,在 `http` 節點啟用中介軟體。
|
||||
|
||||
```php
|
||||
@ -211,6 +214,20 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
- 或者新增監聽器
|
||||
|
||||
開啟 `config/autoload/listeners.php` 檔案,新增監聽器。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
\Hyperf\Tracer\Listener\RequestTraceListener::class,
|
||||
];
|
||||
```
|
||||
|
||||
### 配置 Span tag
|
||||
|
||||
對於一些 Hyperf 自動收集追蹤資訊的 Span Tag 名稱,可以透過更改 Span Tag 配置來更改對應的名稱,只需在配置檔案 `config/autolaod/opentracing.php` 內增加 `tags` 配置即可,參考配置如下。如配置項存在,則以配置項的值為準,如配置項不存在,則以元件的預設值為準。
|
||||
|
114
src/tracer/src/Listener/RequestTraceListener.php
Normal file
114
src/tracer/src/Listener/RequestTraceListener.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Tracer\Listener;
|
||||
|
||||
use Hyperf\Coroutine\Coroutine;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\HttpMessage\Exception\HttpException;
|
||||
use Hyperf\HttpServer\Event\RequestHandled;
|
||||
use Hyperf\HttpServer\Event\RequestReceived;
|
||||
use Hyperf\HttpServer\Event\RequestTerminated;
|
||||
use Hyperf\Tracer\SpanStarter;
|
||||
use Hyperf\Tracer\SpanTagManager;
|
||||
use Hyperf\Tracer\SwitchManager;
|
||||
use Hyperf\Tracer\TracerContext;
|
||||
use OpenTracing\Span;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Swow\Psr7\Message\ResponsePlusInterface;
|
||||
use Throwable;
|
||||
|
||||
class RequestTraceListener implements ListenerInterface
|
||||
{
|
||||
use SpanStarter;
|
||||
|
||||
public function __construct(private SwitchManager $switchManager, private SpanTagManager $spanTagManager)
|
||||
{
|
||||
}
|
||||
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
RequestReceived::class,
|
||||
RequestHandled::class,
|
||||
RequestTerminated::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event): void
|
||||
{
|
||||
match ($event::class) {
|
||||
RequestReceived::class => $this->handleRequestReceived($event),
|
||||
RequestHandled::class => $this->handleRequestHandled($event),
|
||||
RequestTerminated::class => $this->handleRequestTerminated($event),
|
||||
default => '', // fix phpstan error
|
||||
};
|
||||
}
|
||||
|
||||
protected function handleRequestReceived(RequestReceived $event): void
|
||||
{
|
||||
$this->buildSpan($event->request);
|
||||
}
|
||||
|
||||
protected function handleRequestHandled(RequestHandled $event): void
|
||||
{
|
||||
if ($event->response instanceof ResponsePlusInterface && $traceId = TracerContext::getTraceId()) {
|
||||
$event->response->addHeader('Trace-Id', $traceId);
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleRequestTerminated(RequestTerminated $event): void
|
||||
{
|
||||
$response = $event->response;
|
||||
|
||||
if (! $response) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tracer = TracerContext::getTracer();
|
||||
$span = TracerContext::getRoot();
|
||||
$span->setTag($this->spanTagManager->get('response', 'status_code'), $response->getStatusCode());
|
||||
|
||||
if ($event->exception && $this->switchManager->isEnable('exception')) {
|
||||
$this->appendExceptionToSpan($span, $exception = $event->exception);
|
||||
|
||||
if ($exception instanceof HttpException) {
|
||||
$span->setTag($this->spanTagManager->get('response', 'status_code'), $exception->getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
$span->finish();
|
||||
$tracer->flush();
|
||||
}
|
||||
|
||||
protected function appendExceptionToSpan(Span $span, Throwable $exception): void
|
||||
{
|
||||
$span->setTag('error', true);
|
||||
$span->setTag($this->spanTagManager->get('exception', 'class'), get_class($exception));
|
||||
$span->setTag($this->spanTagManager->get('exception', 'code'), $exception->getCode());
|
||||
$span->setTag($this->spanTagManager->get('exception', 'message'), $exception->getMessage());
|
||||
$span->setTag($this->spanTagManager->get('exception', 'stack_trace'), (string) $exception);
|
||||
}
|
||||
|
||||
protected function buildSpan(ServerRequestInterface $request): Span
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
$span = $this->startSpan(sprintf('request: %s %s', $request->getMethod(), $uri->getPath()));
|
||||
$span->setTag($this->spanTagManager->get('coroutine', 'id'), (string) Coroutine::id());
|
||||
$span->setTag($this->spanTagManager->get('request', 'path'), (string) $uri->getPath());
|
||||
$span->setTag($this->spanTagManager->get('request', 'method'), $request->getMethod());
|
||||
$span->setTag($this->spanTagManager->get('request', 'uri'), (string) $uri);
|
||||
foreach ($request->getHeaders() as $key => $value) {
|
||||
$span->setTag($this->spanTagManager->get('request', 'header') . '.' . $key, implode(', ', $value));
|
||||
}
|
||||
return $span;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user