getsentry / getsentry/sentry-ruby

Tracing does not work with ActiveController::Live actions

未关闭
#2,355 3 条评论 0 个 reaction 已指派 1 人 已被 @sl0thentr0py 认领 在 GitHub 查看
Feature Ruby sentry-rails Traces
主要语言
Ruby
星标
987
派生
541
平均合并
17 小时 40 分钟
30 天内合并 PR
19

描述

### Issue Description

[`ActiveController::Live`](https://api.rubyonrails.org/v7.1.3.4/classes/ActionController/Live.html) is a Rails module to enable livestreaming of server responses. It's quite useful to do things like generating CSVs.

The way it works internally, however, makes it problematic to use with Sentry. `ActionController::Live` executes all actions in a *separate thread* from the original controller thread. This means that any Sentry traces will not work, as the middleware which starts a transaction only applies to a particular thread.

I was actually able to fix this by creating the following patch. It basically tells sentry to treat the spawned thread like it is a new part of a distributed trace. I'm not exactly familiar with this library, though, so it's sort of... Gross. There's probably a better way to do it.

```ruby
module ActionControllerLiveSentryPatch
def new_controller_thread
opts = sentry_propagation_hash
super do
scope = Sentry.get_current_scope
transaction = scope && Sentry.start_transaction(
op: "action_controller.live_action",
name: scope.transaction_name,
source: scope.transaction_source,
**opts
)
scope&.set_span(transaction)

res = yield
transaction&.set_http_status(response&.status)
res
rescue StandardError
transaction&.set_http_status(500)
raise
ensure
transaction&.finish
end
end

def sentry_propagation_hash
context = Sentry.get_current_scope&.propagation_context
span = Sentry.get_current_scope&.get_span

return {} unless context && span

{
trace_id: span.trace_id,
parent_span_id: span.span_id,
parent_sampled: span.sampled
}.tap do |hash|
baggage_str = span.to_baggage
next unless baggage_str.present?

hash.merge!(baggage: Sentry::Baggage.from_incoming_header(baggage_str))
end
end
end

```

### Reproduction Steps

1. Create a Rails application
2. Add sentry with tracing enabled
3. Include `ActiveController::Live` in some controller and add actions that would log to sentry (IE, they do DB queries or whatever)
4. Make requests against that controller

### Expected Behavior

We should see traces from the controller action in Sentry.

### Actual Behavior

We only see one overall HTTP trace in Sentry for the entire action, with no sub-traces.

### Ruby Version

3.3.3

### SDK Version

5.18.2

### Integration and Its Version

Rails 5.18.2

### Sentry Config

```ruby
Sentry.init do |config|
config.dsn = ENV.fetch("SENTRY_DSN", nil)
config.breadcrumbs_logger = %i[active_support_logger]

# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
# We recommend adjusting this value in production.
config.traces_sample_rate = 1
# Set profiles_sample_rate to profile 100%
# of sampled transactions.
# We recommend adjusting this value in production.
config.profiles_sample_rate = 1

config.logger = Logger.new($stdout)
config.logger.level = :debug

# config.enabled_environments = %w[production]
end
```

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。