Skip to content
This repository has been archived by the owner on Jan 27, 2020. It is now read-only.

Commit

Permalink
Merge pull request mastodon#1309 from pixiv/add_sentry
Browse files Browse the repository at this point in the history
Add sentry
  • Loading branch information
abcang committed Oct 9, 2019
2 parents e505ad6 + f1b1ee7 commit d6ef839
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,13 @@ gem 'rdf-normalize', '~> 0.3'
# pawoo extra
gem 'exception_notification'
gem 'slack-notifier'
gem 'sentry-raven'
gem 'type_attributes'
gem 'activerecord-import'
gem 'elasticsearch-model', '~> 5.0'
gem 'switch_point'
gem 'exponent-server-sdk'
gem "recaptcha"
gem 'recaptcha'

group :development, :test do
gem 'spring'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,8 @@ GEM
scss_lint (0.57.0)
rake (>= 0.9, < 13)
sass (~> 3.5.5)
sentry-raven (2.11.3)
faraday (>= 0.7.6, < 1.0)
shellany (0.0.1)
sidekiq (5.1.3)
concurrent-ruby (~> 1.0)
Expand Down Expand Up @@ -835,6 +837,7 @@ DEPENDENCIES
ruby-progressbar (~> 1.4)
sanitize (~> 4.6)
scss_lint (~> 0.57)
sentry-raven
sidekiq (~> 5.1)
sidekiq-bulk (~> 0.1.1)
sidekiq-scheduler (~> 2.2)
Expand Down
6 changes: 6 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class ApplicationController < ActionController::Base
before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
before_action :check_suspension, if: :user_signed_in?

before_action :set_pawoo_sentry_user

def raise_not_found
raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}"
end
Expand Down Expand Up @@ -149,4 +151,8 @@ def set_cache_headers
def skip_session!
request.session_options[:skip] = true
end

def set_pawoo_sentry_user
Raven.user_context(id: current_user.id) if current_user
end
end
110 changes: 110 additions & 0 deletions config/initializers/raven.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# frozen_string_literal: true

Raven.configure do |config|
config.dsn = ENV['PAWOO_SENTRY_RAILS']

# Sentry通知を有効にしたいRAILS_ENV
config.environments = %w[production]

config.async = ->(event) {
Thread.new { Raven.send_event(event) }
}

# Sentryに送信したくないエラー
config.excluded_exceptions += %w[
ActionController::InvalidAuthenticityToken
ActionController::BadRequest
ActionController::UnknownFormat
ActionController::ParameterMissing
ActiveRecord::RecordNotUnique
Mastodon::UnexpectedResponseError
Mastodon::RaceConditionError
Mastodon::HostValidationError
]

network_exceptions = %w[
HTTP::StateError
HTTP::TimeoutError
HTTP::ConnectionError
HTTP::Redirector::TooManyRedirectsError
HTTP::Redirector::EndlessRedirectError
OpenSSL::SSL::SSLError
Stoplight::Error::RedLight
Net::ReadTimeout
].freeze

def ignore_by_sidekiq(exception_name, network_exceptions)
sidekiq = Raven::Context.current.extra.dig(:sidekiq)
return false unless sidekiq

network_workers = %w[
LinkCrawlWorker
ProcessingWorker
ThreadResolveWorker
NotificationWorker
Import::RelationshipWorker
Web::PushNotificationWorker
].freeze

ignore_worker_errors = {
'ActivityPub::ProcessingWorker' => ['ActiveRecord::RecordInvalid'],
'LinkCrawlWorker' => ['ActiveRecord::RecordInvalid'],
}.freeze

ignore_job_errors = {
'ActionMailer::DeliveryJob' => ['ActiveJob::DeserializationError']
}.freeze

worker_class = sidekiq.dig('class')
return true if ignore_worker_errors[worker_class]&.include?(exception_name)

# ActivityPub or Pubsubhubbub or 通信が頻繁に発生するWorkerではネットワーク系の例外を無視
if worker_class.start_with?('ActivityPub::') || worker_class.start_with?('Pubsubhubbub::') || network_workers.include?(worker_class)
return true if network_exceptions.include?(exception_name)
end

# ActiveJob
if worker_class == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'
return true if ignore_job_errors[sidekiq.dig('wrapped')]&.include?(exception_name)
end

false
end


def ignore_by_controller(exception_name, network_exceptions)
controller_class = Raven::Context.current.rack_env['action_controller.instance']&.class
return false unless controller_class

network_controllers_or_concerns = %w[
RemoteFollowController
SignatureVerification
].freeze

ignore_controller_errors = {
'MediaProxyController' => ['ActiveRecord::RecordInvalid'],
}.freeze

return true if ignore_controller_errors[controller_class.name]&.include?(exception_name)

# SignatureVerificationがincludeされているコントローラ or 通信が頻繁に発生するコントローラではネットワーク系のエラーを無視
if controller_class.ancestors.any? { |klass| network_controllers_or_concerns.include?(klass.name) }
return true if network_exceptions.include?(exception_name)
end

false
end

config.should_capture = ->(message_or_exc) do
return true unless message_or_exc.is_a? Exception

exception_name = message_or_exc.class.name

# includes invalid characters
return false if exception_name == 'ActiveRecord::RecordInvalid' && exception.message.end_with?('includes invalid characters')
return false if ignore_by_sidekiq(exception_name, network_exceptions)
return false if ignore_by_controller(exception_name, network_exceptions)

true
end
end

0 comments on commit d6ef839

Please sign in to comment.