From ae9abcc43802e6943f3474567d8b96d181ccd13a Mon Sep 17 00:00:00 2001 From: lixinhan <327902941@qq.com> Date: Thu, 12 Oct 2023 15:55:30 +0800 Subject: [PATCH] Added `Hyperf\Tracer\Aspect\GrpcAspect` (#6203) Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com> --- publish/opentracing.php | 1 + src/Aspect/CoroutineAspect.php | 2 +- src/Aspect/DbAspect.php | 2 +- src/Aspect/ElasticserachAspect.php | 2 +- src/Aspect/GrpcAspect.php | 130 ++++++++++++++++++++++++++ src/Aspect/HttpClientAspect.php | 2 +- src/Aspect/MethodAspect.php | 2 +- src/Aspect/RedisAspect.php | 2 +- src/Aspect/RpcAspect.php | 2 +- src/Aspect/TraceAnnotationAspect.php | 2 +- src/ConfigProvider.php | 2 + src/Listener/RequestTraceListener.php | 2 +- src/Middleware/TraceMiddleware.php | 2 +- src/SpanTagManager.php | 4 + src/SwitchManager.php | 5 +- 15 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 src/Aspect/GrpcAspect.php diff --git a/publish/opentracing.php b/publish/opentracing.php index 6f773b1..0e675fb 100644 --- a/publish/opentracing.php +++ b/publish/opentracing.php @@ -20,6 +20,7 @@ 'db' => env('TRACER_ENABLE_DB', false), 'elasticserach' => env('TRACER_ENABLE_ELASTICSERACH', false), 'exception' => env('TRACER_ENABLE_EXCEPTION', false), + 'grpc' => env('TRACER_ENABLE_GRPC', false), 'guzzle' => env('TRACER_ENABLE_GUZZLE', false), 'method' => env('TRACER_ENABLE_METHOD', false), 'redis' => env('TRACER_ENABLE_REDIS', false), diff --git a/src/Aspect/CoroutineAspect.php b/src/Aspect/CoroutineAspect.php index ea2b18e..3536ce1 100644 --- a/src/Aspect/CoroutineAspect.php +++ b/src/Aspect/CoroutineAspect.php @@ -58,7 +58,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) $callable(); } catch (Throwable $e) { - if (isset($child) && $this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if (isset($child) && $this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $child->setTag('error', true); $child->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); } diff --git a/src/Aspect/DbAspect.php b/src/Aspect/DbAspect.php index 701e2f2..c5c0dda 100644 --- a/src/Aspect/DbAspect.php +++ b/src/Aspect/DbAspect.php @@ -46,7 +46,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) try { $result = $proceedingJoinPoint->process(); } catch (Throwable $e) { - if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $span->setTag('error', true); $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); } diff --git a/src/Aspect/ElasticserachAspect.php b/src/Aspect/ElasticserachAspect.php index 8722f4c..e38ceb9 100644 --- a/src/Aspect/ElasticserachAspect.php +++ b/src/Aspect/ElasticserachAspect.php @@ -57,7 +57,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) try { $result = $proceedingJoinPoint->process(); } catch (Throwable $e) { - if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $span->setTag('error', true); $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); } diff --git a/src/Aspect/GrpcAspect.php b/src/Aspect/GrpcAspect.php new file mode 100644 index 0000000..1ec5f0e --- /dev/null +++ b/src/Aspect/GrpcAspect.php @@ -0,0 +1,130 @@ +switchManager = $container->get(SwitchManager::class); + $this->spanTagManager = $container->get(SpanTagManager::class); + $this->context = $container->get(Context::class); + } + + public function process(ProceedingJoinPoint $proceedingJoinPoint) + { + if (! $this->switchManager->isEnable('grpc')) { + return $proceedingJoinPoint->process(); + } + + return match ($proceedingJoinPoint->methodName) { + 'send' => $this->processSend($proceedingJoinPoint), + 'recv' => $this->processRecv($proceedingJoinPoint), + default => $proceedingJoinPoint->process(), + }; + } + + private function processSend(ProceedingJoinPoint $proceedingJoinPoint) + { + $arguments = $proceedingJoinPoint->getArguments(); + /** @var Request $request */ + $request = $arguments[0]; + $key = "GRPC send [{$request->path}]"; + $span = $this->startSpan($key); + $carrier = []; + // Injects the context into the wire + TracerContext::getTracer()->inject( + $span->getContext(), + TEXT_MAP, + $carrier + ); + + // Merge tracer info + $request->headers = array_merge($request->headers, $carrier); + if ($this->spanTagManager->has('grpc', 'request.header')) { + foreach ($request->headers as $key => $value) { + $span->setTag($this->spanTagManager->get('grpc', 'request.header') . '.' . $key, $value); + } + } + + $this->context->set('tracer.carrier', $carrier); + CT::set('tracer.span.' . static::class, $span); + + try { + return $proceedingJoinPoint->process(); + } catch (Throwable $e) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { + $span->setTag('error', true); + $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); + } + throw $e; + } + } + + private function processRecv(ProceedingJoinPoint $proceedingJoinPoint) + { + /** @var null|Span $span */ + $span = CT::get('tracer.span.' . static::class); + + try { + /** @var bool|Response $result */ + $result = $proceedingJoinPoint->process(); + if ($result instanceof Response) { + if ($this->spanTagManager->has('grpc', 'response.header')) { + foreach ($result->headers as $key => $value) { + $span?->setTag($this->spanTagManager->get('grpc', 'response.header') . '.' . $key, $value); + } + } + } + } catch (Throwable $e) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + $span?->setTag('error', true); + $span?->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); + } + throw $e; + } finally { + $span?->finish(); + } + + return $result; + } +} diff --git a/src/Aspect/HttpClientAspect.php b/src/Aspect/HttpClientAspect.php index 036873d..42699b5 100644 --- a/src/Aspect/HttpClientAspect.php +++ b/src/Aspect/HttpClientAspect.php @@ -80,7 +80,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) $span->setTag($this->spanTagManager->get('http_client', 'http.status_code'), $result->getStatusCode()); } } catch (Throwable $e) { - if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $span->setTag('error', true); $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); } diff --git a/src/Aspect/MethodAspect.php b/src/Aspect/MethodAspect.php index 72f5832..b32a54a 100644 --- a/src/Aspect/MethodAspect.php +++ b/src/Aspect/MethodAspect.php @@ -43,7 +43,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) try { $result = $proceedingJoinPoint->process(); } catch (Throwable $e) { - if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $span->setTag('error', true); $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); } diff --git a/src/Aspect/RedisAspect.php b/src/Aspect/RedisAspect.php index 0b537de..782725e 100644 --- a/src/Aspect/RedisAspect.php +++ b/src/Aspect/RedisAspect.php @@ -47,7 +47,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) $result = $proceedingJoinPoint->process(); $span->setTag($this->spanTagManager->get('redis', 'result'), json_encode($result)); } catch (Throwable $e) { - if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $span->setTag('error', true); $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); } diff --git a/src/Aspect/RpcAspect.php b/src/Aspect/RpcAspect.php index e1a9a41..f903e66 100644 --- a/src/Aspect/RpcAspect.php +++ b/src/Aspect/RpcAspect.php @@ -78,7 +78,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) try { $result = $proceedingJoinPoint->process(); } catch (Throwable $e) { - if (($span = CT::get('tracer.span.' . static::class)) && $this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if (($span = CT::get('tracer.span.' . static::class)) && $this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $span->setTag('error', true); $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); CT::set('tracer.span.' . static::class, $span); diff --git a/src/Aspect/TraceAnnotationAspect.php b/src/Aspect/TraceAnnotationAspect.php index c17279a..0e44cb1 100644 --- a/src/Aspect/TraceAnnotationAspect.php +++ b/src/Aspect/TraceAnnotationAspect.php @@ -50,7 +50,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) try { $result = $proceedingJoinPoint->process(); } catch (Throwable $e) { - if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e::class)) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($e)) { $span->setTag('error', true); $span->log(['message', $e->getMessage(), 'code' => $e->getCode(), 'stacktrace' => $e->getTraceAsString()]); } diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index ae73216..257a5d4 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -15,6 +15,7 @@ use Hyperf\Tracer\Aspect\CoroutineAspect; use Hyperf\Tracer\Aspect\CreateTraceContextAspect; use Hyperf\Tracer\Aspect\ElasticserachAspect; +use Hyperf\Tracer\Aspect\GrpcAspect; use Hyperf\Tracer\Aspect\HttpClientAspect; use Hyperf\Tracer\Aspect\RedisAspect; use Hyperf\Tracer\Aspect\RpcAspect; @@ -52,6 +53,7 @@ public function __invoke(): array CoroutineAspect::class, CreateTraceContextAspect::class, ElasticserachAspect::class, + GrpcAspect::class, HttpClientAspect::class, RedisAspect::class, RpcAspect::class, diff --git a/src/Listener/RequestTraceListener.php b/src/Listener/RequestTraceListener.php index 8ee24d8..5cbf008 100644 --- a/src/Listener/RequestTraceListener.php +++ b/src/Listener/RequestTraceListener.php @@ -77,7 +77,7 @@ protected function handleRequestTerminated(RequestTerminated $event): void $span = TracerContext::getRoot(); $span->setTag($this->spanTagManager->get('response', 'status_code'), $response->getStatusCode()); - if ($event->exception && $this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($event->exception::class)) { + if ($event->exception && $this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($event->exception)) { $this->appendExceptionToSpan($span, $exception = $event->exception); if ($exception instanceof HttpException) { diff --git a/src/Middleware/TraceMiddleware.php b/src/Middleware/TraceMiddleware.php index 922a34e..40009cc 100644 --- a/src/Middleware/TraceMiddleware.php +++ b/src/Middleware/TraceMiddleware.php @@ -58,7 +58,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface } $span->setTag($this->spanTagManager->get('response', 'status_code'), $response->getStatusCode()); } catch (Throwable $exception) { - if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($exception::class)) { + if ($this->switchManager->isEnable('exception') && ! $this->switchManager->isIgnoreException($exception)) { $this->appendExceptionToSpan($span, $exception); } if ($exception instanceof HttpException) { diff --git a/src/SpanTagManager.php b/src/SpanTagManager.php index b3456e6..07f3bbf 100644 --- a/src/SpanTagManager.php +++ b/src/SpanTagManager.php @@ -19,6 +19,10 @@ class SpanTagManager 'http.method' => 'http.method', 'http.status_code' => 'http.status_code', ], + 'grpc' => [ + 'request.header' => 'grpc.request.header', + 'response.header' => 'grpc.response.header', + ], 'redis' => [ 'arguments' => 'redis.arguments', 'result' => 'redis.result', diff --git a/src/SwitchManager.php b/src/SwitchManager.php index a24866b..ebe8d2c 100644 --- a/src/SwitchManager.php +++ b/src/SwitchManager.php @@ -13,6 +13,7 @@ use Hyperf\Context\Context; use OpenTracing\Span; +use Throwable; class SwitchManager { @@ -50,11 +51,11 @@ public function isEnable(string $identifier): bool return $this->config[$identifier] && Context::get('tracer.root') instanceof Span; } - public function isIgnoreException(string $className): bool + public function isIgnoreException(Throwable|string $exception): bool { $ignoreExceptions = $this->config['ignore_exceptions'] ?? []; foreach ($ignoreExceptions as $ignoreException) { - if (is_a($className, $ignoreException, true)) { + if (is_a($exception, $ignoreException, true)) { return true; } }