Skip to content
Merged
9 changes: 8 additions & 1 deletion src/sentry/src/Aspect/RedisAspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand All @@ -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;
}

Expand Down
3 changes: 3 additions & 0 deletions src/sentry/src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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' => [
Expand Down
57 changes: 57 additions & 0 deletions src/sentry/src/Listener/RedisCommandExecutedListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);
/**
* This file is part of friendsofhyperf/components.
*
* @link https://github.com/friendsofhyperf/components
* @document https://github.com/friendsofhyperf/components/blob/main/README.md
* @contact huangdijia@gmail.com
*/

namespace FriendsOfHyperf\Sentry\Listener;

use FriendsOfHyperf\Sentry\Integration;
use FriendsOfHyperf\Sentry\Switcher;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Redis\Event\CommandExecuted;
use Sentry\Breadcrumb;

class RedisCommandExecutedListener implements ListenerInterface
{
public function __construct(private Switcher $switcher)
{
}

public function listen(): array
{
return [
CommandExecuted::class,
];
}

/**
* @param object|CommandExecuted $event
*/
public function process(object $event): void
{
if (
! $this->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,
]
));
}
}
41 changes: 41 additions & 0 deletions src/sentry/src/Listener/SetRedisEventEnableListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);
/**
* This file is part of friendsofhyperf/components.
*
* @link https://github.com/friendsofhyperf/components
* @document https://github.com/friendsofhyperf/components/blob/main/README.md
* @contact huangdijia@gmail.com
*/

namespace FriendsOfHyperf\Sentry\Listener;

use Hyperf\Contract\ConfigInterface;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Framework\Event\BootApplication;

class SetRedisEventEnableListener implements ListenerInterface
{
public function __construct(protected ConfigInterface $config)
{
}

public function listen(): array
{
return [
BootApplication::class,
];
}

public function process(object $event): void
{
if (! $this->config->has('redis')) {
return;
}

foreach ($this->config->get('redis', []) as $pool => $_) {
$this->config->set("redis.{$pool}.event.enable", true);
}
}
}
8 changes: 7 additions & 1 deletion src/sentry/src/Tracing/Aspect/RedisAspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
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;
use Sentry\Tracing\SpanStatus;
use Throwable;

/**
* @deprecated since v3.1, will be removed in v3.2.
*
* @property string $poolName
* @method array getConfig()
* @property array $config
Expand All @@ -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();
}

Expand Down
102 changes: 102 additions & 0 deletions src/sentry/src/Tracing/Listener/TracingRedisListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);
/**
* This file is part of friendsofhyperf/components.
*
* @link https://github.com/friendsofhyperf/components
* @document https://github.com/friendsofhyperf/components/blob/main/README.md
* @contact huangdijia@gmail.com
*/

namespace FriendsOfHyperf\Sentry\Tracing\Listener;

use FriendsOfHyperf\Sentry\Switcher;
use FriendsOfHyperf\Sentry\Tracing\SpanStarter;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Coroutine\Coroutine;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Redis\Event\CommandExecuted;
use Hyperf\Redis\Pool\PoolFactory;
use Psr\Container\ContainerInterface;
use Sentry\Tracing\SpanStatus;

class TracingRedisListener implements ListenerInterface
{
use SpanStarter;

public function __construct(
private ContainerInterface $container,
private ConfigInterface $config,
private Switcher $switcher
) {
}

public function listen(): array
{
return [
CommandExecuted::class,
];
}

/**
* @param object|CommandExecuted $event
*/
public function process(object $event): void
{
if (! $this->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();
}
}