From dd154238d172c27c8d5e88da0e10f4aeec25ab69 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:11:46 +0800 Subject: [PATCH 1/5] fix: improve database read/write connection tracing - Add TRACE_DB_USE_READ_PDO constant to track read PDO usage - Enhance DbConnectionAspect to detect getPdoForSelect method calls - Improve EventHandleListener to properly determine server port based on read/write configuration and host matching - Fix port detection for read replicas in database tracing This ensures accurate server address and port tracing for both read and write database connections, especially in environments with separate read/write hosts and ports. --- src/sentry/src/Constants.php | 2 ++ .../src/Tracing/Aspect/DbConnectionAspect.php | 7 ++++++- .../Tracing/Listener/EventHandleListener.php | 17 +++++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/sentry/src/Constants.php b/src/sentry/src/Constants.php index 735f4417a..da8ec9caf 100644 --- a/src/sentry/src/Constants.php +++ b/src/sentry/src/Constants.php @@ -15,6 +15,8 @@ class Constants { public const TRACE_CARRIER = 'sentry.tracing.trace_carrier'; + public const TRACE_DB_USE_READ_PDO = 'sentry.tracing.db.use_read_pdo'; + public const TRACE_DB_SERVER_ADDRESS = 'sentry.tracing.db.server.address'; public const TRACE_DB_SERVER_PORT = 'sentry.tracing.db.server.port'; diff --git a/src/sentry/src/Tracing/Aspect/DbConnectionAspect.php b/src/sentry/src/Tracing/Aspect/DbConnectionAspect.php index 109f573e1..925d0f760 100644 --- a/src/sentry/src/Tracing/Aspect/DbConnectionAspect.php +++ b/src/sentry/src/Tracing/Aspect/DbConnectionAspect.php @@ -28,7 +28,12 @@ class DbConnectionAspect extends AbstractAspect public function process(ProceedingJoinPoint $proceedingJoinPoint) { - return tap($proceedingJoinPoint->process(), function ($pdo) { + return tap($proceedingJoinPoint->process(), function ($pdo) use ($proceedingJoinPoint) { + if ($proceedingJoinPoint->methodName === 'getPdoForSelect') { + $arguments = $proceedingJoinPoint->arguments['keys'] ?? []; + Context::set(Constants::TRACE_DB_USE_READ_PDO, $arguments['useReadPdo'] ?? false); + } + Context::getOrSet(self::class, function () use ($pdo) { $connectionStatus = $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS); [$host] = explode(' ', $connectionStatus); diff --git a/src/sentry/src/Tracing/Listener/EventHandleListener.php b/src/sentry/src/Tracing/Listener/EventHandleListener.php index 71e3ac35a..2a81e1275 100644 --- a/src/sentry/src/Tracing/Listener/EventHandleListener.php +++ b/src/sentry/src/Tracing/Listener/EventHandleListener.php @@ -186,6 +186,19 @@ protected function handleDbQueryExecuted(DbEvent\QueryExecuted $event): void $data['db.collection.name'] = $sqlParse['table']; } + // Get port from config + $host = (string) Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost'); + if (! Context::has(Constants::TRACE_DB_SERVER_PORT)) { + $useReadPdo = (bool) Context::get(Constants::TRACE_DB_USE_READ_PDO, false); + $dbConfig = $this->config->get('databases.' . $event->connectionName, []); + $hosts = $useReadPdo ? ($dbConfig['read']['host'] ?? $dbConfig['write']['host'] ?? [$dbConfig['host']]) : ($dbConfig['write']['host'] ?? [$dbConfig['host']]); + $ports = $useReadPdo ? ($dbConfig['read']['port'] ?? $dbConfig['write']['port'] ?? [$dbConfig['port']]) : ($dbConfig['write']['port'] ?? [$dbConfig['port']]); + $index = array_find_key($hosts, fn ($item) => $item == $host); + $port = $ports[$index] ?? 3306; + } else { + $port = (int) Context::get(Constants::TRACE_DB_SERVER_PORT); + } + $pool = $this->container->get(PoolFactory::class)->getPool($event->connectionName); $data += [ 'db.pool.name' => $event->connectionName, @@ -193,8 +206,8 @@ protected function handleDbQueryExecuted(DbEvent\QueryExecuted $event): void 'db.pool.max_idle_time' => $pool->getOption()->getMaxIdleTime(), 'db.pool.idle' => $pool->getConnectionsInChannel(), 'db.pool.using' => $pool->getCurrentConnections(), - 'server.address' => (string) Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost'), - 'server.port' => (int) Context::get(Constants::TRACE_DB_SERVER_PORT, 3306), + 'server.address' => $host, + 'server.port' => $port, ]; if ($this->feature->isTracingTagEnabled('db.sql.bindings', true)) { From 5424af37429a7980a1210ccf0e4e1a32b5c4d927 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:13:15 +0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E8=BF=9E=E6=8E=A5=E4=B8=BB=E6=9C=BA=E5=92=8C=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E7=9A=84=E9=80=89=E6=8B=A9=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Tracing/Listener/EventHandleListener.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sentry/src/Tracing/Listener/EventHandleListener.php b/src/sentry/src/Tracing/Listener/EventHandleListener.php index 2a81e1275..14ef9e16e 100644 --- a/src/sentry/src/Tracing/Listener/EventHandleListener.php +++ b/src/sentry/src/Tracing/Listener/EventHandleListener.php @@ -191,10 +191,14 @@ protected function handleDbQueryExecuted(DbEvent\QueryExecuted $event): void if (! Context::has(Constants::TRACE_DB_SERVER_PORT)) { $useReadPdo = (bool) Context::get(Constants::TRACE_DB_USE_READ_PDO, false); $dbConfig = $this->config->get('databases.' . $event->connectionName, []); - $hosts = $useReadPdo ? ($dbConfig['read']['host'] ?? $dbConfig['write']['host'] ?? [$dbConfig['host']]) : ($dbConfig['write']['host'] ?? [$dbConfig['host']]); - $ports = $useReadPdo ? ($dbConfig['read']['port'] ?? $dbConfig['write']['port'] ?? [$dbConfig['port']]) : ($dbConfig['write']['port'] ?? [$dbConfig['port']]); + $hosts = $dbConfig['write']['host'] ?? [$dbConfig['host']]; + $ports = $dbConfig['write']['port'] ?? [$dbConfig['port']]; + if ($useReadPdo) { + $hosts = $dbConfig['read']['host'] ?? $hosts; + $ports = $dbConfig['read']['port'] ?? $ports; + } $index = array_find_key($hosts, fn ($item) => $item == $host); - $port = $ports[$index] ?? 3306; + $port = $ports[$index] ?? $ports[0] ?? 3306; } else { $port = (int) Context::get(Constants::TRACE_DB_SERVER_PORT); } From 1aec424322c40530952bde586e57d65ffa37ff76 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:19:57 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E9=85=8D=E7=BD=AE=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E6=9B=B4=E7=81=B5=E6=B4=BB=E7=9A=84?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Listener/EventHandleListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/src/Tracing/Listener/EventHandleListener.php b/src/sentry/src/Tracing/Listener/EventHandleListener.php index 14ef9e16e..caf4a14f3 100644 --- a/src/sentry/src/Tracing/Listener/EventHandleListener.php +++ b/src/sentry/src/Tracing/Listener/EventHandleListener.php @@ -190,7 +190,7 @@ protected function handleDbQueryExecuted(DbEvent\QueryExecuted $event): void $host = (string) Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost'); if (! Context::has(Constants::TRACE_DB_SERVER_PORT)) { $useReadPdo = (bool) Context::get(Constants::TRACE_DB_USE_READ_PDO, false); - $dbConfig = $this->config->get('databases.' . $event->connectionName, []); + $dbConfig = (fn () => $this->config ?? ['host' => 'localhost', 'port' => 3306])->call($event->connection); $hosts = $dbConfig['write']['host'] ?? [$dbConfig['host']]; $ports = $dbConfig['write']['port'] ?? [$dbConfig['port']]; if ($useReadPdo) { From 1396619481213de8fe25b597e78b7c5b029387e5 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:22:28 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=20array=5Fsearch?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=BB?= =?UTF-8?q?=E6=9C=BA=E6=9F=A5=E6=89=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Listener/EventHandleListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/src/Tracing/Listener/EventHandleListener.php b/src/sentry/src/Tracing/Listener/EventHandleListener.php index caf4a14f3..8fe74ccdc 100644 --- a/src/sentry/src/Tracing/Listener/EventHandleListener.php +++ b/src/sentry/src/Tracing/Listener/EventHandleListener.php @@ -197,7 +197,7 @@ protected function handleDbQueryExecuted(DbEvent\QueryExecuted $event): void $hosts = $dbConfig['read']['host'] ?? $hosts; $ports = $dbConfig['read']['port'] ?? $ports; } - $index = array_find_key($hosts, fn ($item) => $item == $host); + $index = array_search($host, $hosts, true); $port = $ports[$index] ?? $ports[0] ?? 3306; } else { $port = (int) Context::get(Constants::TRACE_DB_SERVER_PORT); From e60fe6aeea78ddb6457e5c71f77a9d7b6ede5b4f Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:25:01 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E9=85=8D=E7=BD=AE=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A5=E4=BD=BF=E7=94=A8=E6=AD=A3=E7=A1=AE=E7=9A=84=E4=B8=BB?= =?UTF-8?q?=E6=9C=BA=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Listener/EventHandleListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/src/Tracing/Listener/EventHandleListener.php b/src/sentry/src/Tracing/Listener/EventHandleListener.php index 8fe74ccdc..67cc2a743 100644 --- a/src/sentry/src/Tracing/Listener/EventHandleListener.php +++ b/src/sentry/src/Tracing/Listener/EventHandleListener.php @@ -190,7 +190,7 @@ protected function handleDbQueryExecuted(DbEvent\QueryExecuted $event): void $host = (string) Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost'); if (! Context::has(Constants::TRACE_DB_SERVER_PORT)) { $useReadPdo = (bool) Context::get(Constants::TRACE_DB_USE_READ_PDO, false); - $dbConfig = (fn () => $this->config ?? ['host' => 'localhost', 'port' => 3306])->call($event->connection); + $dbConfig = (fn () => $this->config ?? ['host' => $host, 'port' => 3306])->call($event->connection); $hosts = $dbConfig['write']['host'] ?? [$dbConfig['host']]; $ports = $dbConfig['write']['port'] ?? [$dbConfig['port']]; if ($useReadPdo) {