Skip to content

Instantly share code, notes, and snippets.

@2called-chaos
Created May 16, 2020 17:37
Show Gist options
  • Save 2called-chaos/bca40ebed59d4621739f419b49611c4f to your computer and use it in GitHub Desktop.
Save 2called-chaos/bca40ebed59d4621739f419b49611c4f to your computer and use it in GitHub Desktop.

Revisions

  1. 2called-chaos created this gist May 16, 2020.
    138 changes: 138 additions & 0 deletions z_airbrake.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,138 @@
    Airbrake.configure do |config|
    # project specific
    config.project_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

    # use git SHA & current commit as app version
    # Looks like this:
    # Ruby: 2.7.0 » Rails: 6.0.2.2 » f98b36585 - Only try to remove fade from modals if jQuery is there
    config.app_version = "Ruby: #{RUBY_VERSION} » Rails: #{Rails::VERSION::STRING} » " << `cd #{Rails.root} && git log -1 --pretty="%h - %B" HEAD`

    # can always be 1
    config.project_id = 1

    # errbit host, always the same
    config.host = 'https://err.example.net'

    # ignore exceptions in test/dev
    config.ignore_environments = %w[development test]

    # set app root directory
    config.root_directory = Rails.root

    # set current environment
    config.environment = Rails.env

    # log to own file
    config.logger = Logger.new(Rails.root.join("log/airbrake.log"))

    # filter_parameter_logging.rb must run first! This is why this file starts with z_
    config.blacklist_keys = Rails.application.config.filter_parameters

    # disable features errbit cannot handle (and spams log)
    config.job_stats = false
    config.query_stats = false
    config.performance_stats = false
    end



    # ==========================
    # = Annotate notifications =
    # ==========================

    # A filter that collects request body information. Enable it if you are sure you
    # don't send sensitive information to Airbrake in your body (such as passwords).
    # https://github.com/airbrake/airbrake#requestbodyfilter
    Airbrake.add_filter(Airbrake::Rack::RequestBodyFilter.new)

    # Annotate via filter
    Airbrake.add_filter do |notice|
    # you might want to look deeper into what notice contains in your case,
    # the following things are somewhat project-specific.
    ctx = notice[:context]

    # remove thread shit from params hash
    notice[:params].delete(:thread)

    # add link to user
    if uid = ctx.dig(:user, :id)
    ctx[:user][:backend_link] = "https://www.example.com/admin/users/#{uid}"
    end

    # add headers to environment
    if headers = ctx[:headers]
    headers.each do |k,v|
    nk = k.to_s.gsub(".", "_").upcase
    next if AIRBRAKE_IGNORE_ENV.include?(nk)
    notice[:environment][nk] = v.to_s
    end
    end

    # add request env to environment *sigh*
    if env = notice.stash[:rack_request]&.env
    env.each do |k,v|
    nk = k.to_s.gsub(".", "_").upcase
    next if AIRBRAKE_IGNORE_ENV.include?(nk)
    notice[:environment][nk] = v.to_s
    end
    end

    # cleanup env hash
    notice[:environment] = notice[:environment].reject{|k,v| v.blank? }.sort_by{|k, v| k.to_s }.to_h
    end



    # =========================
    # = Ignore exceptions/env =
    # =========================
    AIRBRAKE_IGNORE_ENV = [
    'ACTION_CONTROLLER_INSTANCE',
    'ACTION_DISPATCH_BACKTRACE_CLEANER',
    'ACTION_DISPATCH_COOKIES',
    'ACTION_DISPATCH_COOKIES_DIGEST',
    'ACTION_DISPATCH_COOKIES_SERIALIZER',
    'ACTION_DISPATCH_ENCRYPTED_COOKIE_SALT',
    'ACTION_DISPATCH_ENCRYPTED_SIGNED_COOKIE_SALT',
    'ACTION_DISPATCH_HTTP_AUTH_SALT',
    'ACTION_DISPATCH_KEY_GENERATOR',
    'ACTION_DISPATCH_LOGGER',
    'ACTION_DISPATCH_ROUTES',
    'ACTION_DISPATCH_SECRET_KEY_BASE',
    'ACTION_DISPATCH_SECRET_TOKEN',
    'ACTION_DISPATCH_SIGNED_COOKIE_SALT',
    # 'RACK_ERRORS',
    # 'RACK_INPUT',
    # 'RACK_SESSION',
    # 'RACK_SESSION_OPTIONS',
    ]
    AIRBRAKE_IGNORE_EXCEPTIONS = [
    'ActiveRecord::RecordNotFound',
    'ActionController::RoutingError',
    'ActionController::UnknownFormat',
    'ActionController::UnknownAction',
    #'AbstractController::ActionNotFound',
    #'ActionController::UnknownHttpMethod',
    'ActionController::InvalidAuthenticityToken',
    'Mime::Type::InvalidMimeType',
    #'CGI::Session::CookieStore::TamperedWithCookie',
    ]

    # Ignore exceptions by class
    Airbrake.add_filter do |notice|
    if notice[:errors].any? { |error| AIRBRAKE_IGNORE_EXCEPTIONS.include?(error[:type]) }
    notice.ignore!
    end
    end

    # Ignore utf8 errors on /search
    Airbrake.add_filter do |notice|
    notice.ignore! if notice[:errors].any?{|error|
    error[:type] == "ActionController::BadRequest" &&
    (
    error[:message].to_s.downcase.start_with?("invalid query parameters: non utf-8 value:") ||
    error[:message].to_s.downcase.start_with?("invalid query parameters: invalid encoding for parameter") ||
    error[:message].to_s.downcase.start_with?("invalid path parameters: invalid encoding for parameter")
    )
    }
    end