Tracing does not work with ActiveController::Live actions
Opened this issue · 3 comments
Issue Description
ActiveController::Live
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.
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
- Create a Rails application
- Add sentry with tracing enabled
- Include
ActiveController::Live
in some controller and add actions that would log to sentry (IE, they do DB queries or whatever) - 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
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
thanks @AnthonySuper yea it would be nice to have first class support for this. I'll add it to our backlog and hopefully add it in the coming month or so.
Awesome! If you would like I could also try to make a patch - The code I have now could probably be cleaned up and be automatically prepended by the gem.
yes PRs are always welcome to speed things up!