exception_notificationプラグインでクローラーからのアクセスによる例外を無視する

現在運用しているアプリにexception_notificationというプラグインを入れています。

これはproduction環境において、例外が発生した際に、その内容をメールで通知してくれるというものです。

とても便利なのですが、長いこと使っていて気になることがあります・・・

それは、クローラーからのアクセスによる例外がやたらと多いことです(´・ω・`)

放置すると例外通知メールがとんでもない量になってしまいます。


ということで、ちょっと前にこのプラグインに、「指定したクローラーがアクセスした時に発生する例外を無視」するように改修しました。
GitHub - tiwakawa/exception_notification: Exception Notifier Plugin for Rails

lib/exception_notifier.rb
     unless Array.wrap(options[:ignore_exceptions]).include?(exception.class)
-      Notifier.exception_notification(env, exception).deliver
-      env['exception_notifier.delivered'] = true
+      unless ignore_crawler_match?(env['HTTP_USER_AGENT'])
+        Notifier.exception_notification(env, exception).deliver
+        env['exception_notifier.delivered'] = true
+      else
+        Rails.logger.info "ExceptionNotifier ignored the exception by \"#{env['HTTP_USER_AGENT']}\""
+        Rails.logger.flush
+      end
     end

+  private
+  def ignore_crawler_match?(user_agent)
+    @options[:ignore_crawler].each do |crawler|
+      return true if !!(user_agent =~ Regexp.new(crawler))
+    end if @options[:ignore_crawler]
+    false
+  end

修正した箇所は上記の通りです。

ignore_crawler_match?というメソッドを追加し、その中で、
アクセスしたユーザーエージェントが、指定されたクローラー名と正規表現でマッチするか判定しています。

マッチしなかった場合は、通常とおりメールを送信します。
マッチした場合は、ログに「例外を無視した」旨を出力し、メールは送信されません。


設定方法は簡単です。

config/initializers/exception_notifier.rbといったファイル内で、
:ignore_crawlerオプションを指定するだけです。

MystyleMobile::Application.config.middleware.use ExceptionNotifier,
  :email_prefix => "[Whatever] ",
  :sender_address => %{"notifier" <notifier@example.com>},
  :exception_recipients => %w{exceptions@example.com},
  :ignore_crawler => %w{Y!J- Googlebot}

上記の例では
YahooのクローラーとGooglebotからのアクセスによる例外を無視できます。

これで、だいぶメールが少なくなりました。
この設定をしたアプリと、しないアプリを比べてみたら、現時点で送られてくるメール数が約20倍ほど違っていましたww


ちなみに、最近本家のexception_notificationプラグインを見てみたら、同様にクローラーによるアクセスを無視する処理が追加されていましたね。
Add :ignore_crawlers options. · smartinez87/exception_notification@2e36818 · GitHub