getsentry / getsentry/sentry-ruby
Tracing does not work with ActiveController::Live actions
- Lenguaje dominante
- Ruby
- Estrellas
- 987
- Forks
- 541
- Merge medio
- 17 h 40 min
- PR fusionados (30 d)
- 19
Descripción
### 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
```
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.