getsentry / getsentry/sentry-ruby

Tracing does not work with ActiveController::Live actions

Đang mở
#2,355 3 bình luận 0 reaction 1 người được giao Được @sl0thentr0py nhận Xem trên GitHub
Feature Ruby sentry-rails Traces
Ngôn ngữ chính
Ruby
Star
987
Fork
541
Merge trung bình
17 giờ 40 phút
Pull request đã merge (30 ngày)
19

Mô tả

### 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
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.