鍒嗕韩涓涓猦yperf鐨刧rpc 鏃ュ織鍒囬潰, 瀵逛簬 gRPC 鎺ュ彛锛岀敱浜庤繑鍥炵殑鏄 Protocol Buffers 鏍煎紡鐨勬秷鎭紙message锛,鎵鏈夐渶瑕佺壒娈婂鐞嗕竴涓嬨
<?php
declare(strict_types=1);
namespace App\Aspect;
use Hyperf\Codec\Json;
use Hyperf\Context\Context;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Grpc\Parser;
use Hyperf\GrpcClient\GrpcClient;
use Hyperf\GrpcClient\Request;
use Swoole\Http2\Response;
use Throwable;
#[Aspect]
class GrpcLogAspect extends AbstractAspect
{
public array $classes = [
GrpcClient::class . '::send',
GrpcClient::class . '::recv',
];
#[Inject]
protected StdoutLoggerInterface $logger;
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
return match ($proceedingJoinPoint->methodName) {
'send' => $this->send($proceedingJoinPoint),
'recv' => $this->recv($proceedingJoinPoint),
default => $proceedingJoinPoint->process(),
};
}
private function send(ProceedingJoinPoint $proceedingJoinPoint)
{
$request = $proceedingJoinPoint->getArguments()[0];
$logInfo = [];
if ($request instanceof Request) {
// 鎴彇path涓殑鏂规硶鍚 涓虹被鍚
$path = explode('/', $request->path);
// 鎴彇$path[1].鍓嶉潰鐨勫瓧绗︿覆
$serviceName = substr($path[1], 0, strpos($path[1], '.'));
// $path[2]棣栧瓧姣嶅ぇ鍐
$methodName = ucfirst($path[2]);
$className = $serviceName . '\\' . $methodName;
Context::set('grpcSendClassName', $className);
$data = Parser::deserializeMessage([$className . 'Request', 'decode'], $request->data);
$logInfo = [
'path' => $request->path,
'method' => $request->method,
'header' => $request->headers,
'cookies' => $request->cookies,
'pipeline' => $request->pipeline,
'usePipelineRead' => $request->usePipelineRead,
];
$this->logger->info(sprintf('grpc send: %s, data: %s', Json::encode($logInfo), $data->serializeToJsonString()));
}
try {
$result = $proceedingJoinPoint->process();
} catch (Throwable $th) {
$this->logger->error(sprintf('grpc send error: %s, %s, %s', $th->getMessage(), $th->getCode(), $th->getTraceAsString()));
throw $th;
}
return $result;
}
private function recv(ProceedingJoinPoint $proceedingJoinPoint)
{
try {
$response = $proceedingJoinPoint->process();
if ($response instanceof Response) {
$className = Context::get('grpcSendClassName');
$data = Parser::deserializeMessage([$className . 'Response', 'decode'], $response->data);
$logInfo = [
'streamId' => $response->streamId,
'errCode' => $response->errCode,
'statusCode' => $response->statusCode,
'pipeline' => $response->pipeline,
'cookies' => $response->cookies,
'headers' => $response->headers,
'set_cookie_headers' => $response->set_cookie_headers,
];
$this->logger->info(sprintf('grpc recv: %s, data: %s', Json::encode($logInfo), $data->serializeToJsonString()));
}
} catch (Throwable $th) {
$this->logger->error(sprintf('grpc recv error: %s, %s, %s', $th->getMessage(), $th->getCode(), $th->getTraceAsString()));
throw $th;
}
return $response;
}
}