Last active
June 9, 2022 00:25
-
-
Save 2called-chaos/07a62137b75a4bf2261a328bc94ed26f to your computer and use it in GitHub Desktop.
Airbrake config example for Errbit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Airbrake.configure do |config| | |
# project specific | |
config.project_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' | |
# use git SHA & current commit as app version | |
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.com' | |
# 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")) | |
config.logger.level = Logger::INFO | |
# filter_parameter_logging.rb must run first! This is why this file starts with z_ | |
# Rails guarantees alphabetical execution of initializers! | |
config.blocklist_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 | |
config.remote_config = 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 | |
class PatchedAirbrakeBodyFilter < Airbrake::Rack::RequestBodyFilter | |
# @see Airbrake::FilterChain#refine | |
def call(notice) | |
return unless (request = notice.stash[:rack_request]) | |
return unless request.body | |
if request.body.respond_to?(:read) | |
notice[:environment][:body] = request.body.read(@length) | |
request.body.rewind | |
else | |
notice[:environment][:body] = request.body.to_s | |
end | |
end | |
end | |
Airbrake.add_filter(PatchedAirbrakeBodyFilter.new) | |
# Annotate via filter | |
Airbrake.add_filter do |notice| | |
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.net/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', | |
'ActionController::InvalidCrossOriginRequest', | |
'ActionController::InvalidAuthenticityToken', | |
#'ActionController::UnknownHttpMethod', | |
#'AbstractController::ActionNotFound', | |
#'CGI::Session::CookieStore::TamperedWithCookie', | |
'Mime::Type::InvalidMimeType', | |
#'PaymentAdapter::ProviderTemporarilyUnreachable', | |
] | |
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment