Skip to content

ActiveRecord breadcrumbs aren't emitted inside graphql-ruby queries (Transactions lost when switching to different fibres) #1374

@lukel97

Description

@lukel97

Describe the bug
I'm trying to integrate performance monitoring for a GraphQL API server that uses graphql-ruby on rails. Breadcrumbs for ActiveRecord queries are emitted fine up until Schema.execute, at which point no more breadcrumbs are logged:

class GraphQLController < ApplicationController
  def execute
    scope = Sentry.get_current_scope
    p scope.get_transaction # returns a transaction
    result = Schema.execute(params[:query], variables: prepare_variables(params[:variables]), operation_name: params[:operation_name])
    p scope.get_transaction # returns the same transaction
    render json: result
  rescue => e
    raise e unless Rails.env.development?
    handle_error_in_development e
  end
# more stuff...
end

The weird thing is is that inside my GraphQL schema class, if I log the scope and transaction, the scope is different and the transaction is nil:

# somewhere where Schema.execute calls
def foo
  p Sentry.get_current_scope # a different scope from the one inside my controller
  p Sentry.get_current_scope.get_transaction # nil!
end

This is why I believe the activerecord subscriber isn't emitting any breadcrumbs. And I believe this is happening because graphql-ruby does this execution on different fibres (same thread though). Thus the hub ends up getting cloned:

def get_current_hub
# we need to assign a hub to the current thread if it doesn't have one yet
#
# ideally, we should do this proactively whenever a new thread is created
# but it's impossible for the SDK to keep track every new thread
# so we need to use this rather passive way to make sure the app doesn't crash
Thread.current[THREAD_LOCAL] || clone_hub_to_current_thread
end

But once it's cloned the transaction is lost.

To Reproduce

Create a new rails project, install graphql-ruby, try getting the current transaction from inside your schema/types. I think it might be possible to make a smaller test case by doing something with fibres yourself.

Expected behavior

get_current_scope and get_current_transaction return the same scope and transaction as the originating fibre/inside the action controller, and any activerecord queries are added as breadcrumbs.

Actual behavior
get_current_scope returns a different scope and get_current_transaction returns nil, and no activerecord queries are added to sentry as breadcrumbs

Environment

  • Ruby Version: 3
  • SDK Version:
    • sentry-ruby 4.3.1
    • sentry-rails 4.3.3
  • Integration Versions (if any):
  • Rails 6.1.3.1
  • graphql-ruby 1.12.6

Raven Config

This is not necessary but could be helpful.

Sentry.init do |config|
  config.dsn = 'blah'
  config.breadcrumbs_logger = [:active_support_logger]
  config.traces_sample_rate = 0.2
end

Metadata

Metadata

Assignees

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions