Skip to content

Commit

Permalink
Adds Tracing\CacheAspect (#714)
Browse files Browse the repository at this point in the history
* Adds `Tracing\CacheAspect`

* Refactor CacheAspect to handle cache clearing

* Refactor CacheAspect to handle cache clearing

* Refactor CacheAspect to handle cache clearing in ConfigProvider

* Refactor CacheAspect to handle cache clearing in ConfigProvider

* Refactor CacheAspect to handle cache clearing in ConfigProvider

* Refactor cache aspect to enable cache clearing in ConfigProvider

* Refactor CacheAspect to remove unnecessary code in handleClear method

* Refactor CacheAspect to remove unnecessary code in process method

* Revert "Refactor CacheAspect to remove unnecessary code in process method"

This reverts commit 0a272b4.

* Refactor CacheAspect to remove unnecessary code in process method

* Refactor CacheAspect to add cache fetching in process method

* Refactor RedisAspect to improve key handling in process method

* Refactor TracingCommandListener to improve data handling in process method

---------

Co-authored-by: Deeka Wong <[email protected]>
  • Loading branch information
huangdijia and huangdijia authored Sep 19, 2024
1 parent 7924bd3 commit b80a5c2
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/sentry/publish/sentry.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
'enable' => [
'amqp' => env('SENTRY_TRACING_ENABLE_AMQP', true),
'async_queue' => env('SENTRY_TRACING_ENABLE_ASYNC_QUEUE', true),
'cache' => env('SENTRY_TRACING_ENABLE_CACHE', true),
'command' => env('SENTRY_TRACING_ENABLE_COMMAND', true),
'crontab' => env('SENTRY_TRACING_ENABLE_CRONTAB', true),
'kafka' => env('SENTRY_TRACING_ENABLE_KAFKA', true),
Expand Down
1 change: 1 addition & 0 deletions src/sentry/src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function __invoke(): array
Aspect\SingletonAspect::class,
Tracing\Aspect\AmqpProducerAspect::class,
Tracing\Aspect\AsyncQueueJobMessageAspect::class,
Tracing\Aspect\CacheAspect::class,
Tracing\Aspect\CoordinatorAspect::class,
Tracing\Aspect\CoroutineAspect::class,
Tracing\Aspect\DbAspect::class,
Expand Down
1 change: 1 addition & 0 deletions src/sentry/src/Listener/SetRequestLifecycleListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public function process(object $event): void
'sentry.enable_tracing',
'sentry.tracing.enable.amqp',
'sentry.tracing.enable.async_queue',
'sentry.tracing.enable.cache',
'sentry.tracing.enable.command',
'sentry.tracing.enable.crontab',
'sentry.tracing.enable.kafka',
Expand Down
151 changes: 151 additions & 0 deletions src/sentry/src/Tracing/Aspect/CacheAspect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?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 [email protected]
*/

namespace FriendsOfHyperf\Sentry\Tracing\Aspect;

use FriendsOfHyperf\Sentry\Switcher;
use FriendsOfHyperf\Sentry\Tracing\SpanStarter;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Sentry\SentrySdk;
use Sentry\Tracing\Span;

use function Hyperf\Tappable\tap;

/**
* @see https://develop.sentry.dev/sdk/telemetry/traces/modules/caches/
*/
class CacheAspect extends AbstractAspect
{
use SpanStarter;

public array $classes = [
'Hyperf\Cache\Driver\*Driver::set',
'Hyperf\Cache\Driver\*Driver::setMultiple',
'Hyperf\Cache\Driver\*Driver::fetch',
'Hyperf\Cache\Driver\*Driver::get',
'Hyperf\Cache\Driver\*Driver::getMultiple',
'Hyperf\Cache\Driver\*Driver::delete',
'Hyperf\Cache\Driver\*Driver::deleteMultiple',
'Hyperf\Cache\Driver\*Driver::clear',
];

public function __construct(protected Switcher $switcher)
{
}

public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
if (! $this->switcher->isTracingSpanEnable('cache') || Switcher::isDisableCoroutineTracing()) {
return $proceedingJoinPoint->process();
}

$parent = SentrySdk::getCurrentHub()->getSpan();

try {
$method = $proceedingJoinPoint->methodName;
$op = match ($method) {
'set' => 'cache.put',
'get', 'fetch' => 'cache.get',
'delete' => 'cache.remove',
'setMultiple' => 'cache.put',
'getMultiple' => 'cache.get',
'deleteMultiple' => 'cache.remove',
'clear' => 'cache.flush',
default => 'cache',
};

/** @var string|string[] $key */
$key = match ($method) {
'set', 'get', 'delete', 'setMultiple', 'getMultiple', 'deleteMultiple' => $proceedingJoinPoint->arguments['order'][0] ?? 'unknown',
default => '',
};

$span = $this->startSpan(op: $op, description: $key);

return tap($proceedingJoinPoint->process(), function ($value) use ($span, $method, $key) {
match ($method) {
'set', => $this->handleSet($span, $key, $value),
'get', 'fetch' => $this->handleGet($span, $key, $value),
'delete' => $this->handleDelete($span, $key, $value),
'setMultiple' => $this->handleSetMultiple($span, $key, $value),
'getMultiple' => $this->handleGetMultiple($span, $key, $value),
'deleteMultiple' => $this->handleDeleteMultiple($span, $key, $value),
'clear' => $this->handleClear($span),
default => null,
};
});
} finally {
SentrySdk::getCurrentHub()->setSpan($parent);
}
}

private function handleSet(Span $span, string $key, mixed $value)
{
$span
->setData([
'cache.key' => $key,
])
->finish();
}

private function handleGet(Span $span, string $key, mixed $value)
{
$span
->setData([
'cache.key' => $key,
'cache.hit' => ! is_null($value),
])
->finish();
}

private function handleDelete(Span $span, string $key, mixed $value)
{
$span
->setData([
'cache.key' => $key,
])
->finish();
}

private function handleSetMultiple(Span $span, array $keys, array $values)
{
$span
->setData([
'cache.key' => $keys,
])
->finish();
}

private function handleGetMultiple(Span $span, array $keys, array $values)
{
$span
->setData([
'cache.key' => $keys,
'cache.hit' => ! empty($values),
])
->finish();
}

private function handleDeleteMultiple(Span $span, array $keys, array $values)
{
$span
->setData([
'cache.key' => $keys,
])
->finish();
}

private function handleClear(Span $span)
{
$span->finish();
}
}
3 changes: 2 additions & 1 deletion src/sentry/src/Tracing/Aspect/RedisAspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint)
// rule: operation db.table
// $op = sprintf('%s %s', $arguments['name'], $arguments['arguments']['key'] ?? '');
// $description = sprintf('%s::%s()', $proceedingJoinPoint->className, $arguments['name']);
$key = $arguments['arguments'][0] ?? '';
$op = 'db.redis';
$description = sprintf(
'%s %s',
strtoupper($arguments['name'] ?? ''),
$arguments['arguments'][0] ?? ''
is_array($key) ? implode(',', $key) : $key
);
$span = $this->startSpan($op, $description);

Expand Down
5 changes: 3 additions & 2 deletions src/sentry/src/Tracing/Listener/TracingCommandListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,11 @@ protected function finishTransaction(AfterExecute $event): void
$command = $event->getCommand();

$exitCode = (fn () => $this->exitCode ?? SymfonyCommand::SUCCESS)->call($command);
$data = [];
$tags = [
$data = [
'command.arguments' => (fn () => $this->input->getArguments())->call($command),
'command.options' => (fn () => $this->input->getOptions())->call($command),
];
$tags = [
'command.exit_code' => $exitCode,
];

Expand Down

0 comments on commit b80a5c2

Please sign in to comment.