update
This commit is contained in:
@@ -13,8 +13,8 @@ use Hyperf\ExceptionHandler\ExceptionHandler;
|
||||
use Throwable;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
|
||||
use Hyperf\JsonRpc\Exception\ClientException;
|
||||
use Dhd\Micro\Core\Exception\BusinessException;
|
||||
|
||||
use Dhd\Micro\Core\Trait\RpcContextTrait;
|
||||
@@ -28,22 +28,32 @@ class GatewayExceptionHandler extends ExceptionHandler
|
||||
public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
$this->stopPropagation(); // 阻止异常冒泡
|
||||
|
||||
$traceId = $this->getTraceId();
|
||||
|
||||
|
||||
$code = 500;
|
||||
$message = '服务器内部错误';
|
||||
|
||||
if (($throwable instanceof BusinessException)) {
|
||||
Util::recordLog($throwable->getMessage(), $throwable, $traceId);
|
||||
$code = $throwable->getCode();
|
||||
$message = $throwable->getMessage();
|
||||
} else if ($throwable instanceof ClientException) {
|
||||
} else {
|
||||
$code = $throwable->getCode() ?: 500;
|
||||
$message = $throwable->getMessage() ?: '下游服务异常';
|
||||
Util::recordLog($message, $throwable, $traceId);
|
||||
$message = $throwable->getMessage() ?: '服务异常,请稍后重试';
|
||||
}
|
||||
|
||||
$request = Util::get(RequestInterface::class);
|
||||
Util::logger()->setErrorStatus(!($throwable instanceof BusinessException))
|
||||
->setMessage($message)
|
||||
->setThrowable($throwable)
|
||||
->setTraceId($traceId)
|
||||
->setContext([
|
||||
'url' => $request->getUri(),
|
||||
'method' => $request->getMethod(),
|
||||
'request_data' => $request->all(),
|
||||
])
|
||||
->record();
|
||||
|
||||
$responseData = [
|
||||
'code' => $code,
|
||||
'message' => $message,
|
||||
|
||||
@@ -15,6 +15,7 @@ use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||
|
||||
use Hyperf\RpcClient\Exception\RequestException;
|
||||
use Dhd\Micro\Core\Exception\BusinessException;
|
||||
|
||||
use Dhd\Micro\Core\Trait\RpcContextTrait;
|
||||
@@ -28,21 +29,34 @@ class JsonRpcBusinessExceptionHandler extends ExceptionHandler
|
||||
public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
$this->stopPropagation(); // 阻止异常冒泡
|
||||
|
||||
$traceId = $this->getTraceId();
|
||||
|
||||
$isError = !($throwable instanceof BusinessException);
|
||||
Util::recordLog($isError ? '服务器内部错误' : $throwable->getMessage(), $throwable, $traceId, $isError);
|
||||
|
||||
$request = Util::get(ServerRequestInterface::class);
|
||||
// 关键优化:从 Request 属性中动态获取 ID
|
||||
$id = $request ? $request->getAttribute('request_id', null) : null; // Hyperf 注入的 ID
|
||||
|
||||
$code = 500;
|
||||
$message = '服务器内部错误';
|
||||
|
||||
if (
|
||||
$throwable instanceof RequestException
|
||||
|| $throwable instanceof BusinessException
|
||||
) {
|
||||
$code = $throwable->getCode();
|
||||
$message = $throwable->getMessage();
|
||||
}
|
||||
|
||||
Util::logger()->setErrorStatus(!($throwable instanceof BusinessException))
|
||||
->setMessage($message)
|
||||
->setThrowable($throwable)
|
||||
->setTraceId($traceId)
|
||||
->record();
|
||||
|
||||
$responseData = [
|
||||
'jsonrpc' => '2.0',
|
||||
'id' => $id,
|
||||
'error' => [
|
||||
'code' => $isError ? 500 : $throwable->getCode(),
|
||||
'message' => $isError ? '服务器内部错误' : $throwable->getMessage(),
|
||||
'code' => $code,
|
||||
'message' => $message,
|
||||
'data' => method_exists($throwable, 'getData') ? $throwable->getData() : null,
|
||||
],
|
||||
];
|
||||
|
||||
92
src/Library/Logger.php
Normal file
92
src/Library/Logger.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 日志记录
|
||||
*/
|
||||
|
||||
namespace Dhd\Micro\Core\Library;
|
||||
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use Hyperf\Context\ApplicationContext;
|
||||
use Throwable;
|
||||
|
||||
class Logger
|
||||
{
|
||||
private string $message = '';
|
||||
private ?array $data = null;
|
||||
private ?Throwable $throwable = null;
|
||||
private string $traceId = '';
|
||||
private array $context = [];
|
||||
private bool $isError = false;
|
||||
|
||||
public function setMessage(string $message): self
|
||||
{
|
||||
$this->message = $message;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setData(array $data): self
|
||||
{
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setThrowable(Throwable $throwable): self
|
||||
{
|
||||
$this->throwable = $throwable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTraceId(string $traceId): self
|
||||
{
|
||||
$this->traceId = $traceId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setContext(array $context): self
|
||||
{
|
||||
$this->context = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isError(): bool
|
||||
{
|
||||
return $this->isError;
|
||||
}
|
||||
|
||||
public function setErrorStatus(bool $isError): self
|
||||
{
|
||||
$this->isError = $isError;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function record(): void
|
||||
{
|
||||
$fatory = ApplicationContext::getContainer()->get(LoggerFactory::class);
|
||||
$logger = $fatory->get('log', 'default');
|
||||
$content = [
|
||||
'message' => $this->message,
|
||||
'trace_id' => $this->traceId,
|
||||
'data' => $this->data,
|
||||
'context' => $this->context,
|
||||
];
|
||||
|
||||
if ($this->throwable !== null) {
|
||||
$throwable = $this->throwable;
|
||||
$content['throwable'] = [
|
||||
'message' => $throwable->getMessage(),
|
||||
'code' => $throwable->getCode(),
|
||||
'file' => $throwable->getFile(),
|
||||
'line' => $throwable->getLine(),
|
||||
'trace' => $this->isError ? $throwable->getTrace() : null,
|
||||
'data' => method_exists($throwable, 'getData') ? $throwable->getData() : null,
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->isError) {
|
||||
$logger->error(json_encode($content, JSON_UNESCAPED_UNICODE));
|
||||
} else {
|
||||
$logger->info(json_encode($content, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use Hyperf\Context\ApplicationContext;
|
||||
use Hyperf\Collection\Arr;
|
||||
use Hyperf\Carbon\Carbon;
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use Dhd\Micro\Core\Library\Logger;
|
||||
|
||||
final class Util
|
||||
{
|
||||
@@ -24,41 +25,11 @@ final class Util
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录日志信息
|
||||
*
|
||||
* 此方法使用Hyperf的LoggerFactory创建一个日志记录器,并将指定的消息和数据记录到日志中
|
||||
* 日志内容会被格式化为JSON字符串并以info级别记录
|
||||
*
|
||||
* @param string $msg 日志消息内容
|
||||
* @param mixed $data 需要记录的额外数据,可以是任意类型的数据
|
||||
* @param bool $isError 是否为异常日志,默认为false
|
||||
* @return void
|
||||
*
|
||||
* 示例:
|
||||
* Util::recordLog('用户登录', ['user_id' => 123, 'ip' => '192.168.1.1']);
|
||||
* // 这将在日志中记录类似 {"msg":"用户登录","data":{"user_id":123,"ip":"192.168.1.1"}} 的信息
|
||||
* 获取日志记录器
|
||||
*/
|
||||
public static function recordLog(string $msg, mixed $data, string $traceId = '', bool $isError = false): void
|
||||
public static function logger(): Logger
|
||||
{
|
||||
$fatory = self::get(LoggerFactory::class);
|
||||
$logger = $fatory->get('log', 'default');
|
||||
$content = [
|
||||
'msg' => $msg,
|
||||
'trace_id' => $traceId,
|
||||
'data' => ($data instanceof \Throwable) ? [
|
||||
'message' => $data->getMessage(),
|
||||
'code' => $data->getCode(),
|
||||
'file' => $data->getFile(),
|
||||
'line' => $data->getLine(),
|
||||
'trace' => $isError ? $data->getTrace() : null,
|
||||
'data' => method_exists($data, 'getData') ? $data->getData() : null,
|
||||
] : $data,
|
||||
];
|
||||
if ($isError) {
|
||||
$logger->error(json_encode($content, JSON_UNESCAPED_UNICODE));
|
||||
} else {
|
||||
$logger->info(json_encode($content, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
return new Logger();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user