Skip to content

Conversation

@huangdijia
Copy link
Contributor

@huangdijia huangdijia commented Nov 21, 2025

This PR adds server address and port tracing for database connections, similar to the recent Redis server tracing implementation.

Changes:

  • Added DbConnectionAspect to intercept database connection creation and extract server address information
  • Added TRACE_DB_SERVER_ADDRESS and TRACE_DB_SERVER_PORT constants for context storage
  • Registered the new DbConnectionAspect in ConfigProvider
  • Updated EventHandleListener to include server.address and server.port in database tracing data

The DbConnectionAspect intercepts calls to Connection::getPdoForSelect() and Connection::getPdo() methods, extracts the server address from the PDO connection status, and stores it in the Hyperf context for later use in tracing.

Test Plan:

  • Verify database tracing includes server address and port information
  • Ensure no performance impact on database operations
  • Confirm tracing data is properly populated in Sentry

Summary by CodeRabbit

发布说明

  • 新功能
    • 数据库连接追踪现已捕获并在 SQL 查询追踪中记录数据库服务器地址与端口,提升性能监控与故障排查能力。
    • 增强了对数据库连接信息的上下文采集,相关追踪标签会随查询事件一并上报。

✏️ Tip: You can customize this high-level summary in your review settings.

- Add DbConnectionAspect to capture database server address and port
- Add TRACE_DB_SERVER_ADDRESS and TRACE_DB_SERVER_PORT constants
- Register DbConnectionAspect in ConfigProvider
- Update EventHandleListener to include server.address and server.port in tracing data

This implements similar functionality to Redis server tracing for database connections.
@coderabbitai
Copy link

coderabbitai bot commented Nov 21, 2025

Walkthrough

为 Sentry tracing 添加了对数据库连接信息的捕获:新增 DbConnectionAspect 拦截 Hyperf 数据库连接以记录主机信息,新增常量用于存储地址/端口,并在 EventHandleListener 中将这两项作为 db span 标签输出。

Changes

Cohort / File(s) Change summary
配置
src/sentry/src/ConfigProvider.php
在 ConfigProvider::__invoke() 的 aspects 列表中新增 Tracing\Aspect\DbConnectionAspect::class
常量
src/sentry/src/Constants.php
新增公开常量 TRACE_DB_SERVER_ADDRESSTRACE_DB_SERVER_PORT
Aspect 实现
src/sentry/src/Tracing/Aspect/DbConnectionAspect.php
新增类 DbConnectionAspect;拦截 Hyperf\Database\Connection::getPdoForSelectgetPdo,首次读取 PDO 连接主机信息并通过 Context 存储到 TRACE_DB_SERVER_ADDRESS(按类上下文一次性执行)
事件处理
src/sentry/src/Tracing/Listener/EventHandleListener.php
在数据库查询跨度的 db 数据中新增 server.addressserver.port 标签,值来自 Context 中的 TRACE_DB_SERVER_ADDRESS / TRACE_DB_SERVER_PORT(含默认回退值)

Sequence Diagram(s)

sequenceDiagram
    participant Request
    participant DbConnectionAspect
    participant PDO
    participant Context
    participant EventHandleListener
    participant TraceSpan

    Request->>DbConnectionAspect: 调用 getPdo()/getPdoForSelect (被拦截)
    DbConnectionAspect->>PDO: proceedingJoinPoint.process()
    PDO-->>DbConnectionAspect: 返回 PDO 实例
    alt 首次在当前 Context
        DbConnectionAspect->>PDO: 读取连接信息 (host/port)
        DbConnectionAspect->>Context: Context::getOrSet(TRACE_DB_SERVER_ADDRESS/PORT) 写入
    end
    DbConnectionAspect-->>Request: 返回 PDO

    Request->>EventHandleListener: 生成/结束 SQL span
    EventHandleListener->>Context: 读取 TRACE_DB_SERVER_ADDRESS / TRACE_DB_SERVER_PORT
    EventHandleListener->>TraceSpan: 添加 db.server.address / db.server.port 标签
    EventHandleListener-->>Request: 完成 span 标签注入
Loading

Estimated code review effort

🎯 3 (中等复杂度) | ⏱️ ~20 分钟

需要额外关注:

  • DbConnectionAspect.php$classes 配置是否准确覆盖所有目标方法与版本兼容性。
  • 从 PDO 读取主机/端口的实现对不同驱动(MySQL、Postgres 等)和 DSN 格式的健壮性。
  • Context 写入的并发/幂等性保证,以及 EventHandleListener 中默认回退值是否合理。

Possibly related PRs

Suggested reviewers

  • guandeng
  • xuanyanwow

兔子之歌

🐰 我是小兔去巡查,
拦下连接把主机记,
地址端口放上下文,
追踪跨度里亮晶晶,
跳跃代码庆丰收 ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确描述了主要变更:为数据库连接添加服务器地址追踪,涵盖了该pull request的核心目标。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/db-server-tracing

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.1.32)

At least one path must be specified to analyse.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/sentry/src/Tracing/Listener/EventHandleListener.php (1)

176-198: server.port 始终为默认值 3306,未被实际填充

这里从 Context::get(Constants::TRACE_DB_SERVER_PORT, 3306) 读取端口。验证表明:

  • DbConnectionAspect 中没有任何地方设置过 TRACE_DB_SERVER_PORT 到 Context;
  • 该常量仅定义和使用于此处,不存在任何其他 Context::set 调用;
  • 结果是所有数据库查询的 server.port 总是默认值 3306。

这对非 MySQL 驱动(如 PostgreSQL)或自定义端口配置会产生明显的追踪错误,与 PR 目标"同时追踪地址和端口"不符。

建议至少选一种方案修复:

  1. 在 DbConnectionAspect 中补充设置端口(如果能从连接信息可靠解析);或
  2. 在此处回退到连接配置,确保端口从配置读取:
$defaultPort = (int) ($event->connection->getConfig('port') ?? 3306);

$data += [
    'server.address' => (string) Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost'),
    'server.port' => (int) Context::get(Constants::TRACE_DB_SERVER_PORT, $defaultPort),
];
🧹 Nitpick comments (1)
src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1)

24-38: DbConnectionAspect 建议补充 PDO 类型校验并顺带填充端口信息

整体思路(通过 getPdo* 第一次返回时解析连接信息并写入 Context)是合理的,也和 RedisConnectionAspect 的模式基本一致。不过这里有几个可以改进的点:

  1. $pdo 做类型防御,避免意外 fatal

当前闭包直接调用:

$connectionStatus = $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS);

如果未来某些驱动或自定义 Connection 返回的不是 PDO 实例,会直接触发致命错误。建议加一个轻量的类型检查,例如:

return tap($proceedingJoinPoint->process(), function ($pdo) {
    if (! $pdo instanceof PDO) {
        return;
    }

    if (! Context::get(self::class . '.executed')) {
        $connectionStatus = $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS);
        [$host] = explode(' ', (string) $connectionStatus);

        Context::set(Constants::TRACE_DB_SERVER_ADDRESS, $host);
        Context::set(self::class . '.executed', true);
    }
});

这样在非 PDO 场景下只是丢失 server 信息,不会影响主逻辑执行。

  1. 当前只设置了 address,没有设置 TRACE_DB_SERVER_PORT

本 PR 已经在 Constants 中定义了 TRACE_DB_SERVER_PORT,并在 EventHandleListener 中读取它来填充 server.port,但这里没有写入,导致端口始终使用默认值。可以在解析 ATTR_CONNECTION_STATUS 时顺带尝试拆出端口,例如(示意):

$connectionStatus = $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS);
// 例如 "127.0.0.1:3307 via TCP/IP"
[$hostPort] = explode(' ', (string) $connectionStatus, 2);
[$host, $port] = array_pad(explode(':', $hostPort, 2), 2, null);

Context::set(Constants::TRACE_DB_SERVER_ADDRESS, $host);
if ($port !== null) {
    Context::set(Constants::TRACE_DB_SERVER_PORT, (int) $port);
}
Context::set(self::class . '.executed', true);

这样一来 DB 的 server.address / server.port 就都能根据真实连接信息填充。

  1. (可选)多连接场景下细化 executed 标记

目前的 self::class . '.executed' 是类级别标记,同一协程内如果先后使用多个不同 DB 连接,后面的连接会一直沿用第一次解析到的 host。若你们有多库、多实例的使用场景,可以考虑通过 ProceedingJoinPoint 拿到 Connection 实例,再按连接名或 DSN 维度打标,例如:

$connection = $proceedingJoinPoint->getInstance(); // Hyperf\Database\Connection
$name = method_exists($connection, 'getName') ? $connection->getName() : 'default';
$key = self::class . '.executed.' . $name;

然后用 $key 存储 executed 与对应的 address/port,避免不同连接间互相覆盖。
[recommendation: 建议在后续迭代中根据实际多连接使用情况再考虑这一点。]

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d86e78 and d1e8c7e.

📒 Files selected for processing (4)
  • src/sentry/src/ConfigProvider.php (1 hunks)
  • src/sentry/src/Constants.php (1 hunks)
  • src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1 hunks)
  • src/sentry/src/Tracing/Listener/EventHandleListener.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/sentry/src/Tracing/Listener/EventHandleListener.php (1)
src/sentry/src/Constants.php (1)
  • Constants (14-41)
src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1)
src/sentry/src/Constants.php (1)
  • Constants (14-41)
src/sentry/src/ConfigProvider.php (1)
src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1)
  • DbConnectionAspect (22-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
🔇 Additional comments (2)
src/sentry/src/ConfigProvider.php (1)

30-37: 将 DbConnectionAspect 注册到 aspects 列表是合理的

新增的 Tracing\Aspect\DbConnectionAspect::class 与现有 DbAspect / RedisConnectionAspect 的组织方式一致,能确保新的 DB 连接切面被 AOP 框架正确加载执行,看起来没有问题。

src/sentry/src/Constants.php (1)

18-21: 新增 DB 追踪常量命名合理,但端口常量目前仅被读取未被写入

TRACE_DB_SERVER_ADDRESS / TRACE_DB_SERVER_PORT 的命名和前缀与 Redis、RPC 等现有常量保持一致,便于统一管理 trace key,本身没有问题。

需要注意的是:在当前改动中,只有 TRACE_DB_SERVER_ADDRESSDbConnectionAspect 中被写入 Context;TRACE_DB_SERVER_PORT 虽已定义并在 EventHandleListener 中被读取,但尚未看到有任何写入逻辑,这会导致 server.port 一直走默认值(上一条评论已有展开)。建议后续补齐写入逻辑即可。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1)

31-31: 建议为回调参数添加类型提示。

$pdo 参数添加 PDO 类型提示可以提高代码可读性和类型安全性。

-    return tap($proceedingJoinPoint->process(), function ($pdo) {
+    return tap($proceedingJoinPoint->process(), function (PDO $pdo) {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1e8c7e and 1c94a44.

📒 Files selected for processing (1)
  • src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1)
src/sentry/src/Constants.php (1)
  • Constants (14-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.2
🔇 Additional comments (1)
src/sentry/src/Tracing/Aspect/DbConnectionAspect.php (1)

22-27: 类结构和拦截目标设置正确。

拦截 getPdoForSelectgetPdo 方法能够覆盖数据库连接的主要场景。

@huangdijia huangdijia merged commit e7a25ef into main Nov 21, 2025
22 checks passed
@huangdijia huangdijia deleted the feature/db-server-tracing branch November 21, 2025 07:23
huangdijia added a commit that referenced this pull request Nov 21, 2025
* feat: add server address tracing for database connections

- Add DbConnectionAspect to capture database server address and port
- Add TRACE_DB_SERVER_ADDRESS and TRACE_DB_SERVER_PORT constants
- Register DbConnectionAspect in ConfigProvider
- Update EventHandleListener to include server.address and server.port in tracing data

This implements similar functionality to Redis server tracing for database connections.

* feat: 优化 DbConnectionAspect 以简化数据库连接状态追踪逻辑

---------

Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants