flyerhzm / bullet

help to kill N+1 queries and unused eager loading
MIT License
7.06k stars 432 forks source link

Incorrect semantics for Bullet.stacktrace_excludes #299

Open vergenzt opened 8 years ago

vergenzt commented 8 years ago

According to the readme:

Bullet.stacktrace_excludes: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.

However the option does not appear to be actually working that way. My application uses Rails Admin and I've been getting frequent UnoptimizedQueryErrors for the admin code which I'd like to ignore. I set Bullet.stacktrace_excludes = ['rails_admin'] in my application configuration, but it does not cause Rails Admin errors to be ignored.

After stepping through a debugger, I believe I've found the offending line of code in lib/bullet/detector/n_plus_one_query.rb:

def excluded_stacktrace_path?
  Bullet.stacktrace_excludes.any? do |excluded_path|
    caller_in_project.any? { |c| c.include?(excluded_path) }
  end
end

If this method returns true then the failure gets ignored. Since caller_in_project only returns stack trace lines that are considered to be "in the project", none of them match my "rails_admin" filter since that's an external gem, and the failure does not get filtered.

That middle line should really be the following

caller.any? { |c| c.include?(excluded_path) }

to match the semantics the readme describes of "ignoring paths with any of these substrings in the stack trace, even if they are not in your main app."

vergenzt commented 8 years ago

As a workaround, I'm able to also add 'rails_admin' to Bullet.stacktrace_includes to make Bullet think that rails_admin is a part of my codebase, but this is unintuitive and does not match the descriptions in the readme.

arthurbryant commented 10 months ago

Workaround

You can use RailsAdmin's locale feature to add a around_action to skip bullet.

https://github.com/railsadminteam/rails_admin/wiki/Base-configuration#locale

But make sure only apply to development env as bullet doesn't exist at staging/production env.

config.parent_controller = 'Admin::BaseController' if Rails.env.development
class Admin::BaseController < ActionController::Base
  around_action :skip_bullet

  private

  def skip_bullet
    Bullet.enable = false
    yield
  ensure
    Bullet.enable = true
  end
end