diff --git a/src/sentry/src/Aspect/RedisAspect.php b/src/sentry/src/Aspect/RedisAspect.php index 2c32e729d..cff3593eb 100644 --- a/src/sentry/src/Aspect/RedisAspect.php +++ b/src/sentry/src/Aspect/RedisAspect.php @@ -15,11 +15,15 @@ use FriendsOfHyperf\Sentry\Switcher; use Hyperf\Di\Aop\AbstractAspect; use Hyperf\Di\Aop\ProceedingJoinPoint; +use Hyperf\Redis\Event\CommandExecuted; use Hyperf\Redis\RedisConnection; use Sentry\Breadcrumb; use function Hyperf\Tappable\tap; +/** + * @deprecated since v3.1, will be removed in v3.2. + */ class RedisAspect extends AbstractAspect { public array $classes = [ @@ -36,7 +40,10 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) $startTime = microtime(true); return tap($proceedingJoinPoint->process(), function ($result) use ($arguments, $startTime) { - if (! $this->switcher->isBreadcrumbEnable('redis')) { + if ( + class_exists(CommandExecuted::class) + || ! $this->switcher->isBreadcrumbEnable('redis') + ) { return; } diff --git a/src/sentry/src/ConfigProvider.php b/src/sentry/src/ConfigProvider.php index 79f5f9da5..6c13c400c 100644 --- a/src/sentry/src/ConfigProvider.php +++ b/src/sentry/src/ConfigProvider.php @@ -56,7 +56,9 @@ public function __invoke(): array Listener\CrontabExceptionListener::class, Listener\DbQueryListener::class, Listener\KafkaExceptionListener::class, + Listener\RedisCommandExecutedListener::class, Listener\RequestExceptionListener::class, + Listener\SetRedisEventEnableListener::class, Listener\SetRequestLifecycleListener::class, Crons\Listener\CronEventListener::class, Tracing\Listener\TracingAmqpListener::class, @@ -65,6 +67,7 @@ public function __invoke(): array Tracing\Listener\TracingCrontabListener::class, Tracing\Listener\TracingDbQueryListener::class, Tracing\Listener\TracingKafkaListener::class, + Tracing\Listener\TracingRedisListener::class, Tracing\Listener\TracingRequestListener::class, ], 'annotations' => [ diff --git a/src/sentry/src/Listener/RedisCommandExecutedListener.php b/src/sentry/src/Listener/RedisCommandExecutedListener.php new file mode 100644 index 000000000..218feec12 --- /dev/null +++ b/src/sentry/src/Listener/RedisCommandExecutedListener.php @@ -0,0 +1,57 @@ +switcher->isBreadcrumbEnable('redis') + || ! $event instanceof CommandExecuted + ) { + return; + } + + Integration::addBreadcrumb(new Breadcrumb( + Breadcrumb::LEVEL_INFO, + Breadcrumb::TYPE_DEFAULT, + 'redis', + $event->command, + [ + 'arguments' => $event->parameters, + 'result' => $event->result, + 'duration' => $event->time * 1000, + ] + )); + } +} diff --git a/src/sentry/src/Listener/SetRedisEventEnableListener.php b/src/sentry/src/Listener/SetRedisEventEnableListener.php new file mode 100644 index 000000000..14608ab72 --- /dev/null +++ b/src/sentry/src/Listener/SetRedisEventEnableListener.php @@ -0,0 +1,41 @@ +config->has('redis')) { + return; + } + + foreach ($this->config->get('redis', []) as $pool => $_) { + $this->config->set("redis.{$pool}.event.enable", true); + } + } +} diff --git a/src/sentry/src/Tracing/Aspect/RedisAspect.php b/src/sentry/src/Tracing/Aspect/RedisAspect.php index 16e84f013..a619b78a7 100644 --- a/src/sentry/src/Tracing/Aspect/RedisAspect.php +++ b/src/sentry/src/Tracing/Aspect/RedisAspect.php @@ -16,6 +16,7 @@ use Hyperf\Coroutine\Coroutine; use Hyperf\Di\Aop\AbstractAspect; use Hyperf\Di\Aop\ProceedingJoinPoint; +use Hyperf\Redis\Event\CommandExecuted; use Hyperf\Redis\Pool\PoolFactory; use Hyperf\Redis\Redis; use Psr\Container\ContainerInterface; @@ -23,6 +24,8 @@ use Throwable; /** + * @deprecated since v3.1, will be removed in v3.2. + * * @property string $poolName * @method array getConfig() * @property array $config @@ -43,7 +46,10 @@ public function __construct( public function process(ProceedingJoinPoint $proceedingJoinPoint) { - if (! $this->switcher->isTracingSpanEnable('redis')) { + if ( + class_exists(CommandExecuted::class) + || ! $this->switcher->isTracingSpanEnable('redis') + ) { return $proceedingJoinPoint->process(); } diff --git a/src/sentry/src/Tracing/Listener/TracingRedisListener.php b/src/sentry/src/Tracing/Listener/TracingRedisListener.php new file mode 100644 index 000000000..55ae52f6c --- /dev/null +++ b/src/sentry/src/Tracing/Listener/TracingRedisListener.php @@ -0,0 +1,102 @@ +switcher->isTracingSpanEnable('redis')) { + return; + } + + $pool = $this->container->get(PoolFactory::class)->getPool($event->connectionName); + $config = $this->config->get('redis.' . $event->connectionName, []); + + $data = [ + 'coroutine.id' => Coroutine::id(), + 'duration' => $event->time * 1000, + 'db.system' => 'redis', + 'db.redis.connection' => $event->connectionName, + 'db.redis.database_index' => $config['db'] ?? 0, + 'db.redis.parameters' => $event->parameters, + 'db.statement' => strtoupper($event->command) . implode(' ', $event->parameters), + 'db.redis.pool.name' => $event->connectionName, + 'db.redis.pool.max' => $pool->getOption()->getMaxConnections(), + 'db.redis.pool.max_idle_time' => $pool->getOption()->getMaxIdleTime(), + 'db.redis.pool.idle' => $pool->getConnectionsInChannel(), + 'db.redis.pool.using' => $pool->getCurrentConnections(), + ]; + + // rule: operation db.table + $op = 'db.redis'; + $description = sprintf( + '%s %s', + strtoupper($event->command), + implode(' ', $event->parameters) + ); + $span = $this->startSpan($op, $description); + + if (! $span) { + return; + } + + if ($this->switcher->isTracingExtraTagEnable('redis.result')) { + $data['db.redis.result'] = $event->result; + } + + if ($exception = $event->throwable) { + $span->setStatus(SpanStatus::internalError()); + $span->setTags([ + 'error' => true, + 'exception.class' => $exception::class, + 'exception.message' => $exception->getMessage(), + 'exception.code' => $exception->getCode(), + ]); + if ($this->switcher->isTracingExtraTagEnable('exception.stack_trace')) { + $data['exception.stack_trace'] = (string) $exception; + } + } + + $span->setData($data); + $span->finish(); + } +}