refactor(sentry): replace SpanStarter trait with global functions#920
Conversation
- Create new Function.php with global trace() and startTransaction() functions - Replace SpanStarter trait usage with global function calls across all aspects - Add Function.php to autoload configuration in composer.json files - Mark SpanStarter trait as deprecated with removal notice - Improve code consistency and prepare for trait removal in v3.2 This change provides a cleaner API and reduces trait dependencies while maintaining backward compatibility through deprecation warnings.
|
Warning Rate limit exceeded@huangdijia has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 50 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (3)
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Walkthrough将原本由 SpanStarter trait 提供的 tracing/transaction 启动能力迁移为全局函数( Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor A as 调用方(Aspect/Listener)
participant T as trace(callable, SpanContext)
participant H as Sentry Hub/Scope
participant C as 被包装回调
A->>T: trace(callable, SpanContext)
T->>H: 获取并克隆 Hub,pushScope,设置当前 Span
T->>C: 执行回调
alt 正常返回
C-->>T: result
T->>H: 完成/更新 Span 状态
T-->>A: 返回 result
else 抛出异常
C-->>T: exception
T->>H: 标注 error、记录异常类/码/消息(可选堆栈)
T-->>A: 重新抛出异常
end
sequenceDiagram
autonumber
actor A as 调用方(Aspect/Listener)
participant S as startTransaction(TransactionContext, SamplingCtx)
participant H as Sentry Hub/Scope
A->>S: startTransaction(ctx, samplingCtx)
S->>H: 获取并克隆 Hub,pushScope
S->>H: 开启 Transaction 并将其设为 current span
S-->>A: 返回 Transaction
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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. Comment |
There was a problem hiding this comment.
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 (8)
src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php (1)
71-189: 可能泄露敏感信息:完整请求/响应头部与正文片段上报setData 中包含 http.request.headers、http.response.headers,且响应正文在某些情况下会上传。Headers 常包含 Authorization/Cookie/Set-Cookie/X-API-Key 等敏感信息;正文也可能含 PII。建议最少进行头部白/黑名单过滤,并用开关控制是否上报。
可以局部修正 on_stats 里的 setData 构造,示例(仅示意关键点):
- $span->setData([ + // 构造脱敏后的请求头 + $reqHeaders = $request->getHeaders(); + $sanitizedReqHeaders = []; + foreach ($reqHeaders as $k => $v) { + $lk = strtolower($k); + if (in_array($lk, ['authorization','cookie','proxy-authorization','x-api-key'], true)) { + continue; + } + $sanitizedReqHeaders[$k] = $v; + } + + $data = [ // See: https://develop.sentry.dev/sdk/performance/span-data-conventions/#http 'http.query' => $uri->getQuery(), 'http.fragment' => $uri->getFragment(), 'http.request.method' => $request->getMethod(), 'http.request.body.size' => strlen($options['body'] ?? ''), 'http.request.full_url' => (string) $request->getUri(), 'http.request.path' => $request->getUri()->getPath(), 'http.request.scheme' => $request->getUri()->getScheme(), 'http.request.host' => $request->getUri()->getHost(), 'http.request.port' => $request->getUri()->getPort(), 'http.request.user_agent' => $request->getHeaderLine('User-Agent'), - 'http.request.headers' => $request->getHeaders(), + // 仅在开关开启时上报请求头,且使用脱敏版本 + 'http.request.headers' => $this->switcher->isTracingExtraTagEnabled('http.request.headers') ? $sanitizedReqHeaders : null, // Other 'coroutine.id' => Coroutine::id(), 'http.system' => 'guzzle', 'http.guzzle.config' => $guzzleConfig, 'http.guzzle.options' => $options ?? [], 'duration' => $stats->getTransferTime() * 1000, // in milliseconds - ]); + ]; + // 去除为 null 的键,避免污染数据 + $span->setData(array_filter($data, static fn($v) => $v !== null)); @@ - $span->setData([ - 'http.response.status_code' => $response->getStatusCode(), - 'http.response.reason' => $response->getReasonPhrase(), - 'http.response.headers' => $response->getHeaders(), - 'http.response.body.size' => $response->getBody()->getSize() ?? 0, - 'http.response_content_length' => $response->getHeaderLine('Content-Length'), - 'http.decoded_response_content_length' => $response->getHeaderLine('X-Decoded-Content-Length'), - 'http.response_transfer_size' => $response->getHeaderLine('Content-Length'), - ]); + // 脱敏响应头,仅在开关开启时上报 + $respHeaders = $response->getHeaders(); + $sanitizedRespHeaders = []; + foreach ($respHeaders as $k => $v) { + if (in_array(strtolower($k), ['set-cookie'], true)) { + continue; + } + $sanitizedRespHeaders[$k] = $v; + } + $respData = [ + 'http.response.status_code' => $response->getStatusCode(), + 'http.response.reason' => $response->getReasonPhrase(), + 'http.response.headers' => $this->switcher->isTracingExtraTagEnabled('http.response.headers') ? $sanitizedRespHeaders : null, + 'http.response.body.size' => $response->getBody()->getSize() ?? 0, + 'http.response_content_length' => $response->getHeaderLine('Content-Length'), + 'http.decoded_response_content_length' => $response->getHeaderLine('X-Decoded-Content-Length'), + 'http.response_transfer_size' => $response->getHeaderLine('Content-Length'), + ]; + $span->setData(array_filter($respData, static fn($v) => $v !== null));说明:
- 对敏感头部做黑名单过滤,并以开关控制是否上报 headers。
- 保持已有的 http.response.body.contents 行为受开关控制。
src/sentry/src/Tracing/Aspect/CacheAspect.php (1)
98-102: 修复 strlen(json_encode(...)) 在失败时的类型错误风险
json_encode 失败会返回 false,传入 strlen 会触发 TypeError(PHP 8.1+)。为安全应转为字符串。建议修改为:
- 'item_size' => match (true) { - isset($arguments['value']) => strlen(json_encode($arguments['value'])), - isset($arguments['values']) && is_array($arguments['values']) => strlen(json_encode(array_values($arguments['values']))), - default => 0, - }, + 'item_size' => match (true) { + isset($arguments['value']) => strlen((string) json_encode($arguments['value'])), + isset($arguments['values']) && is_array($arguments['values']) => strlen((string) json_encode(array_values($arguments['values']))), + default => 0, + },src/sentry/src/Tracing/Aspect/AsyncQueueJobMessageAspect.php (1)
96-115: 可能的空 Span 导致 Carrier 构建报错
这里未判断 $scope->getSpan() 结果;若无当前 span,Carrier::fromSpan($span) 可能报错。建议与 AMQP 处一致增加空值保护。建议修改为:
- function (Scope $scope) use ($proceedingJoinPoint, $messageId, $destinationName, $bodySize) { - $span = $scope->getSpan(); - $carrier = Carrier::fromSpan($span)->with([ - 'publish_time' => microtime(true), - 'message_id' => $messageId, - 'destination_name' => $destinationName, - 'body_size' => $bodySize, - ]); - - Context::set(Constants::TRACE_CARRIER, $carrier); + function (Scope $scope) use ($proceedingJoinPoint, $messageId, $destinationName, $bodySize) { + $span = $scope->getSpan(); + if ($span) { + $carrier = Carrier::fromSpan($span)->with([ + 'publish_time' => microtime(true), + 'message_id' => $messageId, + 'destination_name' => $destinationName, + 'body_size' => $bodySize, + ]); + Context::set(Constants::TRACE_CARRIER, $carrier); + } return $proceedingJoinPoint->process(); },src/sentry/src/Tracing/Aspect/DbAspect.php (1)
81-86: 安全遍历绑定参数,避免 foreach(null) 警告
当未提供 bindings 时,foreach 目标可能为 null,存在运行时警告风险。建议改为:
- if ($this->switcher->isTracingExtraTagEnabled('db.sql.bindings', true)) { - $data['db.sql.bindings'] = $arguments['arguments']['bindings'] ?? []; - foreach ($arguments['arguments']['bindings'] as $key => $value) { - $data['db.parameter.' . $key] = $value; - } - } + if ($this->switcher->isTracingExtraTagEnabled('db.sql.bindings', true)) { + $bindings = (array) ($arguments['arguments']['bindings'] ?? []); + $data['db.sql.bindings'] = $bindings; + foreach ($bindings as $key => $value) { + $data['db.parameter.' . $key] = $value; + } + }src/sentry/src/Tracing/Listener/EventHandleListener.php (4)
223-236: 事务 BEGIN 跨度被立即结束,后续 COMMIT/ROLLBACK 结束了错误的 span(严重问题)。这里使用 trace() 会在回调返回后立刻 finish 事务 span;随后的 COMMIT/ROLLBACK 调用 getCurrentHub()->getSpan() 取到的很可能是请求的活动 span(例如 request.received),导致错误的 span 被 finish。
建议显式创建 child span、设置为当前活动 span,并存入 Context 以便后续提交/回滚时准确结束:
- trace( - fn () => null, - SpanContext::make() - ->setOp('db.transaction') - ->setDescription('BEGIN') - ->setOrigin('auto.db') - ->setStartTimestamp(microtime(true)) - ->setData([ - 'coroutine.id' => Coroutine::id(), - 'db.system' => $event->connection->getDriverName(), - 'db.name' => $event->connection->getDatabaseName(), - 'db.pool.name' => $event->connectionName, - ]) - ); + $transaction = SentrySdk::getCurrentHub()->getTransaction(); + if ($transaction) { + $span = $transaction->startChild( + SpanContext::make() + ->setOp('db.transaction') + ->setDescription('BEGIN') + ->setOrigin('auto.db') + ->setStartTimestamp(microtime(true)) + ->setData([ + 'coroutine.id' => Coroutine::id(), + 'db.system' => $event->connection->getDriverName(), + 'db.name' => $event->connection->getDatabaseName(), + 'db.pool.name' => $event->connectionName, + ]) + ); + SentrySdk::getCurrentHub()->setSpan($span); + Context::set('sentry.db.transaction.span.' . $event->connectionName, $span); + }
239-251: COMMIT 结束了当前活动 span 而非事务 span(严重问题)。应取回 BEGIN 时存入 Context 的事务 span 并结束,避免误伤 request.received 等其他 span。
- if (! $span = SentrySdk::getCurrentHub()->getSpan()) { - return; - } - - $span->setStatus(SpanStatus::ok()) - ->setDescription('COMMIT') - ->finish(); + $span = Context::get('sentry.db.transaction.span.' . $event->connectionName); + if (! $span) { + return; + } + $span->setStatus(SpanStatus::ok()) + ->setDescription('COMMIT') + ->finish(); + Context::set('sentry.db.transaction.span.' . $event->connectionName, null); + SentrySdk::getCurrentHub()->setSpan(SentrySdk::getCurrentHub()->getTransaction());
253-265: ROLLBACK 同样结束了错误的 span(严重问题)。与 COMMIT 相同,需用 Context 中保存的事务 span。
- if (! $span = SentrySdk::getCurrentHub()->getSpan()) { - return; - } - - $span->setStatus(SpanStatus::internalError()) - ->setDescription('ROLLBACK') - ->finish(); + $span = Context::get('sentry.db.transaction.span.' . $event->connectionName); + if (! $span) { + return; + } + $span->setStatus(SpanStatus::internalError()) + ->setDescription('ROLLBACK') + ->finish(); + Context::set('sentry.db.transaction.span.' . $event->connectionName, null); + SentrySdk::getCurrentHub()->setSpan(SentrySdk::getCurrentHub()->getTransaction());
458-501: 避免默认记录 Redis 参数,建议受开关控制;同时保持现有结果记录开关。Redis 参数可能包含敏感信息(安全与合规风险)。建议仅在明确开启时记录。
应用以下修改:将参数写入从 setData 初始数组移除,改为在回调中按开关写入。
- trace( - function (Scope $scope) use ($event) { + trace( + function (Scope $scope) use ($event) { if (! $span = $scope->getSpan()) { return; } if ($this->switcher->isTracingExtraTagEnabled('redis.result')) { $span->setData(['db.redis.result' => $event->result]); } + if ($this->switcher->isTracingExtraTagEnabled('redis.parameters')) { + $span->setData(['db.redis.parameters' => $event->parameters]); + } + if ($exception = $event->throwable) { $span->setStatus(SpanStatus::internalError()) ->setTags([ 'error' => 'true', 'exception.class' => $exception::class, 'exception.code' => (string) $exception->getCode(), ]) ->setData([ 'exception.message' => $exception->getMessage(), ]); if ($this->switcher->isTracingExtraTagEnabled('exception.stack_trace')) { $span->setData(['exception.stack_trace' => (string) $exception]); } } }, SpanContext::make() ->setOp('db.redis') ->setDescription($redisStatement) ->setData([ 'coroutine.id' => Coroutine::id(), 'db.system' => 'redis', 'db.statement' => $redisStatement, 'db.redis.connection' => $event->connectionName, 'db.redis.database_index' => $config['db'] ?? 0, - 'db.redis.parameters' => $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(), 'duration' => $event->time * 1000, ]) ->setStartTimestamp(microtime(true) - $event->time / 1000) );
🧹 Nitpick comments (13)
composer.json (1)
238-238: 命名一致性建议:Function.php → Functions.php其它子包普遍采用 Functions.php 命名,建议同一化,降低认知成本(可延后处理,不阻塞合并)。
src/sentry/src/Tracing/SpanStarter.php (6)
40-51: 缺少运行时弃用告警,建议显式触发PR 说明称“trait 方法会发出弃用告警”,当前仅有 PHPDoc 标注,未触发运行时 deprecation。建议在方法入口触发 E_USER_DEPRECATED,便于应用方尽早迁移。
建议改动:
protected function startTransaction(TransactionContext $transactionContext, array $customSamplingContext = []): Transaction { + @trigger_error( + 'FriendsOfHyperf\Sentry\Tracing\SpanStarter::startTransaction() 已废弃,将在 v3.2 移除,请改用 FriendsOfHyperf\Sentry\startTransaction()。', + E_USER_DEPRECATED + );
64-105: 为 trace() 方法也添加弃用告警与上同理,建议在方法开头加入触发弃用提示。
protected function trace(callable $trace, SpanContext $context) { + @trigger_error( + 'FriendsOfHyperf\Sentry\Tracing\SpanStarter::trace() 已废弃,将在 v3.2 移除,请改用 FriendsOfHyperf\Sentry\trace()。', + E_USER_DEPRECATED + );
110-133: 为 startSpan() 添加弃用告警保持一致性。
protected function startSpan( ?string $op = null, ?string $description = null, ?string $origin = null, bool $asParent = false ): ?Span { + @trigger_error( + 'FriendsOfHyperf\Sentry\Tracing\SpanStarter::startSpan() 已废弃,将在 v3.2 移除。', + E_USER_DEPRECATED + );
139-144: 为 startRequestTransaction() 添加弃用告警protected function startRequestTransaction(ServerRequestInterface $request, ...$options): Transaction { + @trigger_error( + 'FriendsOfHyperf\Sentry\Tracing\SpanStarter::startRequestTransaction() 已废弃,将在 v3.2 移除,请改用 FriendsOfHyperf\Sentry\startTransaction()。', + E_USER_DEPRECATED + );
149-152: 为 startCoroutineTransaction() 添加弃用告警protected function startCoroutineTransaction(Span $parent, ...$options): Transaction { + @trigger_error( + 'FriendsOfHyperf\Sentry\Tracing\SpanStarter::startCoroutineTransaction() 已废弃,将在 v3.2 移除,请改用 FriendsOfHyperf\Sentry\startTransaction()。', + E_USER_DEPRECATED + );
157-186: 为 continueTrace() 添加弃用告警protected function continueTrace(string $sentryTrace = '', string $baggage = '', ...$options): Transaction { + @trigger_error( + 'FriendsOfHyperf\Sentry\Tracing\SpanStarter::continueTrace() 已废弃,将在 v3.2 移除,请改用 FriendsOfHyperf\Sentry\startTransaction() + Sentry\continueTrace()。', + E_USER_DEPRECATED + );src/sentry/src/Tracing/Aspect/RedisAspect.php (1)
82-95: 改用全局 trace() 无功能差异,建议附带参数脱敏开关当前已通过 switcher 开关控制 redis.result。建议未来也为 db.redis.parameters 增加可选开关或脱敏(避免把 key/参数原样上传到 Sentry)。
src/sentry/src/Tracing/Aspect/RpcAspect.php (1)
102-122: 为上报的 rpc.context 增加可控与脱敏,避免潜在敏感数据泄露当前会把 Rpc\Context 全量塞进 span data,可能含鉴权/业务敏感信息。建议用开关控制并按需裁剪。
- if ($span && $this->container->has(Rpc\Context::class)) { + if ($span && $this->container->has(Rpc\Context::class)) { // Inject the RPC context data into span. - $span->setData([ - 'rpc.context' => $this->container->get(Rpc\Context::class)->getData(), - ]); + if ($this->switcher->isTracingExtraTagEnabled('rpc.context')) { + $ctxData = $this->container->get(Rpc\Context::class)->getData(); + // 可在此处做白/黑名单过滤 + $span->setData(['rpc.context' => $ctxData]); + }src/sentry/src/Tracing/Aspect/ElasticsearchAspect.php (1)
64-89: 建议将 arguments 记录改为可开关的额外标签,避免高开销与潜在序列化失败
arguments 可能体积大或含不可序列化内容,建议受开关控制,默认不记录。可在当前片段内直接改为条件追加:
- SpanContext::make() + SpanContext::make() ->setOp('db.elasticsearch') ->setDescription(sprintf('%s::%s()', $proceedingJoinPoint->className, $proceedingJoinPoint->methodName)) ->setOrigin('auto.elasticsearch') - ->setData([ - 'coroutine.id' => Coroutine::id(), - 'db.system' => 'elasticsearch', - 'db.operation.name' => $proceedingJoinPoint->methodName, - 'arguments' => (string) json_encode($proceedingJoinPoint->arguments['keys'], JSON_UNESCAPED_UNICODE), - // TODO - // 'http.request.method' => '', - // 'url.full' => '', - // 'server.host' => '', - // 'server.port' => '', - ]) + ->setData([ + 'coroutine.id' => Coroutine::id(), + 'db.system' => 'elasticsearch', + 'db.operation.name' => $proceedingJoinPoint->methodName, + // TODO + // 'http.request.method' => '', + // 'url.full' => '', + // 'server.host' => '', + // 'server.port' => '', + ] + ($this->switcher->isTracingExtraTagEnabled('elasticsearch.arguments') ? [ + 'arguments' => (string) json_encode($proceedingJoinPoint->arguments['keys'], JSON_UNESCAPED_UNICODE), + ] : []))src/sentry/src/Tracing/Listener/EventHandleListener.php (1)
205-214: DB 查询跨度的结束时间可能不被采纳,建议在回调中显式 finish 指定 endTimestamp。Sentry 的 trace() 会在回调返回后自动 finish 当前 span;若仅在 SpanContext 上设置 endTimestamp,finish() 可能用“现在”覆盖,导致时长失真。建议在回调内以事件时长计算的时间戳 finish。
可按以下方式修改本段,确保使用事件耗时作为结束时间:
- trace( - fn () => null, - SpanContext::make() - ->setOp('db.sql.query') - ->setDescription($event->sql) - ->setOrigin('auto.db') - ->setStartTimestamp($startTimestamp) - ->setData($data) - ->setEndTimestamp($startTimestamp + $event->time / 1000) - ); + trace( + function (Scope $scope) use ($event, $startTimestamp) { + $scope->getSpan()?->finish($startTimestamp + $event->time / 1000); + return null; + }, + SpanContext::make() + ->setOp('db.sql.query') + ->setDescription($event->sql) + ->setOrigin('auto.db') + ->setStartTimestamp($startTimestamp) + ->setData($data) + );src/sentry/src/Tracing/Aspect/KafkaProducerAspect.php (1)
62-94: sendAsync 中 body 大小计算对非字符串值不安全,建议显式转为字符串。避免 strlen 非字符串产生警告,建议对 value 做 (string) 转换后再计算长度。
示例(需在本段之外调整定义处):
- $value = (string) ($proceedingJoinPoint->arguments['keys']['value'] ?? '');
- $bodySize = strlen($value);
src/sentry/src/Function.php (1)
52-97: trace 封装合理,异常标注与开关检查完整,LGTM。可选优化:
- 为 trace 声明返回类型 mixed,增强类型提示。
- 函数定义外层增加 function_exists 守卫,避免重复加载时潜在报错(低概率)。
-function trace(callable $trace, SpanContext $context) +function trace(callable $trace, SpanContext $context): mixed可选守卫(示例,需包裹函数定义,非必须):
if (! function_exists(__NAMESPACE__ . '\trace')) { /* 定义 trace */ } if (! function_exists(__NAMESPACE__ . '\startTransaction')) { /* 定义 startTransaction */ }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
composer.json(1 hunks)src/sentry/composer.json(1 hunks)src/sentry/src/Function.php(1 hunks)src/sentry/src/Tracing/Aspect/AmqpProducerAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/AsyncQueueJobMessageAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/CacheAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/CoordinatorAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/CoroutineAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/DbAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/ElasticsearchAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/FilesystemAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/GrpcAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/KafkaProducerAspect.php(3 hunks)src/sentry/src/Tracing/Aspect/RedisAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/RpcAspect.php(2 hunks)src/sentry/src/Tracing/Aspect/TraceAnnotationAspect.php(2 hunks)src/sentry/src/Tracing/Listener/EventHandleListener.php(10 hunks)src/sentry/src/Tracing/SpanStarter.php(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (16)
src/sentry/src/Tracing/Aspect/AsyncQueueJobMessageAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/FilesystemAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Listener/EventHandleListener.php (2)
src/sentry/src/Function.php (2)
startTransaction(30-41)trace(52-97)src/sentry/src/Tracing/SpanStarter.php (2)
startTransaction(40-51)trace(64-105)
src/sentry/src/Tracing/Aspect/AmqpProducerAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/GrpcAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/RpcAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/CoordinatorAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/CacheAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Function.php (3)
src/sentry/class_map/SentrySdk.php (3)
SentrySdk(24-65)setCurrentHub(61-64)getCurrentHub(51-54)src/sentry/src/Tracing/SpanStarter.php (2)
trace(64-105)startTransaction(40-51)src/sentry/src/Switcher.php (2)
isTracingExtraTagEnabled(85-88)Switcher(19-137)
src/sentry/src/Tracing/Aspect/ElasticsearchAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/TraceAnnotationAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/RedisAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/CoroutineAspect.php (2)
src/sentry/src/Function.php (1)
startTransaction(30-41)src/sentry/src/Tracing/SpanStarter.php (1)
startTransaction(40-51)
src/sentry/src/Tracing/Aspect/KafkaProducerAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
src/sentry/src/Tracing/Aspect/DbAspect.php (2)
src/sentry/src/Function.php (1)
trace(52-97)src/sentry/src/Tracing/SpanStarter.php (1)
trace(64-105)
⏰ 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). (11)
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.7
- GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
- 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.1 with Swoole 5.1.7
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.7
- GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.1 with Swoole 5.1.7
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.7
- GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.7
🔇 Additional comments (29)
src/sentry/src/Tracing/Aspect/GrpcAspect.php (1)
66-73: 迁移到全局 trace() 的改动正确语义保持一致,父 Span 存在且采样时才创建子 Span,并注入分布式追踪头。改动 LGTM。
src/sentry/src/Tracing/Aspect/CoordinatorAspect.php (1)
42-52: 改用全局 trace() 实现一致化,LGTM保持原有行为与数据字段,变更安全。
src/sentry/composer.json (1)
49-53: 已验证 Function.php 路径及大小写正确
在子包启用 Function.php 自动加载,符合预期,与根 composer.json 呼应,保证独立安装时可加载全局函数。composer.json (1)
238-238: 确认无重复定义全局函数经检索,
trace()与startTransaction()仅在src/sentry/src/Function.php中以全局函数形式定义;SpanStartertrait 中的同名方法作用于类作用域,不会与全局函数冲突。src/sentry/src/Tracing/Aspect/ElasticsearchAspect.php (1)
21-22: 切换到全局 trace() 导入 — LGTM
实现与全局函数保持一致,清晰简洁。src/sentry/src/Tracing/Aspect/CacheAspect.php (2)
21-21: 切换到全局 trace() 导入 — LGTM
保持与新 API 一致。
69-97: trace 包装迁移 — LGTM
行为保持一致,闭包内通过 tap 注入附加数据的方式清晰。src/sentry/src/Tracing/Aspect/FilesystemAspect.php (2)
21-22: 切换到全局 trace() 导入 — LGTM
风格统一。
34-41: trace 包装迁移 — LGTM
逻辑保持不变,描述和数据结构一致。src/sentry/src/Tracing/Aspect/AmqpProducerAspect.php (2)
27-28: 切换到全局 trace() 导入 — LGTM
符合本次重构方向。
81-116: trace 包装迁移 — LGTM
在闭包中注入 Carrier 并写入 AMQP headers 的逻辑保持一致。src/sentry/src/Tracing/Aspect/TraceAnnotationAspect.php (2)
22-23: 切换到全局 trace() 导入 — LGTM
一致性良好。
55-71: trace 包装迁移 — LGTM
结果数据已受开关 annotation.result 控制,符合预期。src/sentry/src/Tracing/Aspect/AsyncQueueJobMessageAspect.php (1)
25-26: 切换到全局 trace() 导入 — LGTM
无行为变更。src/sentry/src/Tracing/Aspect/DbAspect.php (2)
25-26: 切换到全局 trace() 导入 — LGTM
无功能性风险。
88-103: trace 包装迁移 — LGTM
结果记录已受开关 db.result 控制,行为与原逻辑一致。src/sentry/src/Tracing/Listener/EventHandleListener.php (7)
52-53: 引入全局函数方式正确,LGTM。
305-314: HTTP/RPC 事务启动逻辑清晰,LGTM。
391-399: 命令事务启动迁移到全局函数,LGTM。
512-520: Crontab 事务启动迁移到全局函数,LGTM。
581-589: AMQP 事务启动迁移到全局函数,LGTM。
663-671: Kafka 消费事务启动迁移到全局函数,LGTM。
729-737: 异步队列事务启动迁移到全局函数,LGTM。src/sentry/src/Tracing/Aspect/CoroutineAspect.php (2)
24-24: 引入 startTransaction 全局函数方式正确,LGTM。
93-100: 协程内衍生独立事务的处理方式合理,LGTM。
- 正确使用 continueTrace 继承 traceparent/baggage。
- 作用域隔离依赖 Hub 的协程上下文,不干扰父事务。
src/sentry/src/Tracing/Aspect/KafkaProducerAspect.php (2)
25-26: 迁移到全局 trace 函数,LGTM。
102-129: 批量发送的链路注入与元数据设置正确,LGTM。src/sentry/src/Function.php (2)
30-41: startTransaction 实现与既有 SpanStarter 行为一致,LGTM。
1-97: Composer autoload 配置正确根
composer.json已包含src/sentry/src/Function.php,且src/sentry/composer.json已包含src/Function.php,Function.php 已通过autoload.files正确加载,无需变更。
There was a problem hiding this comment.
Pull Request Overview
This PR refactors the Sentry integration by replacing the SpanStarter trait with global function calls, streamlining the codebase and preparing for future deprecation cleanup.
- Introduces new global
trace()andstartTransaction()functions in Function.php - Replaces trait usage across all aspect classes and listeners with direct function calls
- Marks the SpanStarter trait as deprecated with removal planned for v3.2
Reviewed Changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sentry/src/Function.php | Adds new global functions with error handling and tracing functionality |
| src/sentry/src/Tracing/SpanStarter.php | Marks trait and methods as deprecated with appropriate warnings |
| Multiple Aspect classes | Removes SpanStarter trait usage and replaces with global function calls |
| src/sentry/src/Tracing/Listener/EventHandleListener.php | Updates listener to use global functions instead of trait methods |
| composer.json files | Adds Function.php to autoload configuration |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
…ransaction and trace handling
huangdijia
left a comment
There was a problem hiding this comment.
代码审查反馈
🎯 变更摘要
这个 PR 成功地将 SpanStarter trait 重构为全局函数方式,提供了更简洁的 API 接口。主要变更包括:
- 新增全局函数 trace() 和 startTransaction()
- 更新 15+ 个 Aspect 类移除 trait 依赖
- 保持向后兼容性,trait 标记为弃用
⚠️ 潜在风险
性能考虑:
- 每次调用全局函数都会触发容器解析 Tracer::class,在高并发场景下可能产生性能开销
- 建议考虑缓存 Tracer 实例以优化性能
架构影响:
- 全局函数绕过了依赖注入机制,可能影响单元测试的便利性
- 对 ApplicationContext::getContainer() 的硬依赖可能降低代码可测试性
💡 优化建议
- 性能优化 - 在 Function.php 中添加实例缓存
- 错误处理 - 为全局函数添加容器不可用时的优雅降级机制
- 文档完善 - 建议添加从 trait 到全局函数的迁移指南
✅ 合规性检查
符合项:
- ✅ 命名规范遵循项目约定
- ✅ 正确的命名空间使用
- ✅ 保持了向后兼容性
- ✅ 文件组织结构合理
需要关注:
- 确保新的全局函数有充分的单元测试覆盖
- 考虑为 Tracer 定义接口以提高可测试性
🎉 总体评价
这是一个设计良好的重构,成功简化了 API 并为未来的清理工作做好了准备。代码质量整体良好,主要建议集中在性能优化和测试覆盖方面。
感谢你在保持向后兼容性的同时推进代码现代化!👍
* refactor(sentry): replace SpanStarter trait with global functions - Create new Function.php with global trace() and startTransaction() functions - Replace SpanStarter trait usage with global function calls across all aspects - Add Function.php to autoload configuration in composer.json files - Mark SpanStarter trait as deprecated with removal notice - Improve code consistency and prepare for trait removal in v3.2 This change provides a cleaner API and reduces trait dependencies while maintaining backward compatibility through deprecation warnings. * refactor(trace): simplify tracing extra tag check logic * fix(Function.php): remove unnecessary initialization of isTracingExtraTagEnabled * feat(tracing): implement TracerProvider for transaction and trace management * refactor(tracing): replace TracerProvider with Tracer and update transaction methods * refactor(span): replace SpanStarter methods with Tracer methods for transaction and trace handling --------- Co-Authored-By: Deeka Wong <[email protected]>
Summary
This PR refactors the Sentry integration by replacing the
SpanStartertrait with global function calls, improving code consistency and preparing for deprecation cleanup.Changes Made
trace()andstartTransaction()functionsSpanStartertrait usage across all aspect classes and listeners:Benefits
Migration Path
FriendsOfHyperf\Sentry\trace()andFriendsOfHyperf\Sentry\startTransaction()Test Plan
Summary by CodeRabbit