diff --git a/src/sentry/src/Tracing/Aspect/DbAspect.php b/src/sentry/src/Tracing/Aspect/DbAspect.php index f8e97902e..a0e149272 100644 --- a/src/sentry/src/Tracing/Aspect/DbAspect.php +++ b/src/sentry/src/Tracing/Aspect/DbAspect.php @@ -11,31 +11,45 @@ namespace FriendsOfHyperf\Sentry\Tracing\Aspect; +use FriendsOfHyperf\Sentry\Constants; use FriendsOfHyperf\Sentry\Feature; use FriendsOfHyperf\Sentry\Util\SqlParser; -use Hyperf\DB\DB; +use Hyperf\Context\Context; use Hyperf\DB\Pool\PoolFactory; use Hyperf\Di\Aop\AbstractAspect; use Hyperf\Di\Aop\ProceedingJoinPoint; +use PDO; use Psr\Container\ContainerInterface; use Sentry\State\Scope; use Sentry\Tracing\SpanContext; +use WeakMap; use function FriendsOfHyperf\Sentry\trace; +use function Hyperf\Tappable\tap; /** * @property string $poolName + * @property PDO $connection + * @property array $config */ class DbAspect extends AbstractAspect { public array $classes = [ - DB::class . '::__call', + 'Hyperf\DB\MySQLConnection::reconnect', + 'Hyperf\DB\DB::getConnection', + 'Hyperf\DB\DB::__call', ]; + /** + * @var WeakMap<\Hyperf\DB\AbstractConnection,array> + */ + private WeakMap $serverCache; + public function __construct( protected ContainerInterface $container, protected Feature $feature ) { + $this->serverCache = new WeakMap(); } public function process(ProceedingJoinPoint $proceedingJoinPoint) @@ -44,24 +58,46 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) return $proceedingJoinPoint->process(); } + if ($proceedingJoinPoint->methodName === 'reconnect') { + return tap($proceedingJoinPoint->process(), function () use ($proceedingJoinPoint) { + /** @var \Hyperf\DB\AbstractConnection $connection */ + $connection = $proceedingJoinPoint->getInstance(); + $this->serverCache[$connection] = $connection->getConfig(); + }); + } + + if ($proceedingJoinPoint->methodName === 'getConnection') { + return tap($proceedingJoinPoint->process(), function ($connection) { + /** @var \Hyperf\DB\AbstractConnection $connection */ + $server = $this->serverCache[$connection] ?? null; + if ($server !== null) { + Context::set(Constants::TRACE_DB_SERVER_ADDRESS, $server['host'] ?? 'localhost'); + Context::set(Constants::TRACE_DB_SERVER_PORT, $server['port'] ?? 3306); + } + }); + } + $arguments = $proceedingJoinPoint->arguments['keys']; - $poolName = (fn () => $this->poolName)->call($proceedingJoinPoint->getInstance()); - /** @var \Hyperf\Pool\Pool $pool */ - $pool = $this->container->get(PoolFactory::class)->getPool($poolName); $operation = $arguments['name']; $database = ''; $driver = 'unknown'; - $table = ''; + + /** @var \Hyperf\DB\DB $instance */ + $instance = $proceedingJoinPoint->getInstance(); + $poolName = (fn () => $this->poolName)->call($instance); + /** @var \Hyperf\Pool\Pool $pool */ + $pool = $this->container->get(PoolFactory::class)->getPool($poolName); if ($pool instanceof \Hyperf\DB\Pool\Pool) { $config = $pool->getConfig(); $database = $config['database'] ?? ''; - $driver = $config['driver'] ?? 'unknown'; + $driver = $config['driver'] ?? $driver; } $sql = $arguments['arguments']['query'] ?? ''; $sqlParse = SqlParser::parse($sql); $table = $sqlParse['table']; $operation = $sqlParse['operation']; + $data = [ 'db.system' => $driver, 'db.name' => $database, @@ -72,8 +108,8 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) 'db.pool.max_idle_time' => $pool->getOption()->getMaxIdleTime(), 'db.pool.idle' => $pool->getConnectionsInChannel(), 'db.pool.using' => $pool->getCurrentConnections(), - // 'server.host' => '', - // 'server.port' => '', + 'server.host' => Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost'), + 'server.port' => Context::get(Constants::TRACE_DB_SERVER_PORT, 3306), ]; if ($this->feature->isTracingTagEnabled('db.sql.bindings', true)) {