Gửi exception về mail với gem Exception Notification
Kiểm soát lỗi của một trang web đối với một developer không hề đơn giản, việc ngồi cả ngày để check log của server và tìm xem lỗi từ đâu trong cái danh sách hàng ngàn dòng log thực sự là một việc làm vô ích và lãng phí thời gian cũng như công sức của bản thân. Exception Notification là một gem giúp ...
Kiểm soát lỗi của một trang web đối với một developer không hề đơn giản, việc ngồi cả ngày để check log của server và tìm xem lỗi từ đâu trong cái danh sách hàng ngàn dòng log thực sự là một việc làm vô ích và lãng phí thời gian cũng như công sức của bản thân. Exception Notification là một gem giúp chúng ta quản lý lỗi hệ thống dễ dàng hơn rất nhiều bằng việc gửi thông báo lỗi cho người quản lý hệ thống thông qua email, HipChat, Slack,... Bài viết này mình sẽ hướng dẫn các bạn sử dụng gem Exception Notification
Để sử dụng được Exception Notification, việc đầu tiên cần làm giống như với những gem khác, cần khai báo gem trong Gemfile:
gem "exception_notification"
Hoặc install gem: gem install 'exception_notification'
Tiếp theo, cần thêm config của gem trong environment config hoặc application config
Rails.application.config.middleware.use ExceptionNotification::Rack, :email => { #config for email :email_prefix => "[PREFIX] ", :sender_address => %{"notifier" <notifier@example.com>}, :exception_recipients => %w{exceptions@example.com} } :campfire => { #config for capfire :subdomain => 'my_subdomain', :token => 'my_token', :room_name => 'my_room' } :hipchat => { #config for hipchat :api_token => 'my_token', :room_name => 'my_room' } ...
Ở đây mình chỉ sử dụng phần email, cho nên mình sẽ bỏ qua các phần khác. Các bạn có thể tìm hiểu các tiện ích khác tại đây
Để có thể gửi được mail, bạn sẽ cần phải có config cho ActionMailer, ví dụ:
config.action_mailer.delivery_method = :sendmail # Defaults to: # config.action_mailer.sendmail_settings = { # :location => '/usr/sbin/sendmail', # :arguments => '-i -t' # } config.action_mailer.perform_deliveries = true config.action_mailer.raise_delivery_errors = true
Một số tùy chọn sẵn có cho phần config của ExceptionNotification:
- sender_address: địa chỉ dùng để gửi mail.
Ví dụ:
%("Exception Notifier" exception.notifier@example.com)
- exception_recipients: địa chỉ sẽ nhận được email, có thể là 1 hoặc nhiều mail, được viết cách nhau bởi dấu ','
- email_prefix: Khai báo prefix cho tiêu đề của email
- sections: Những phần sẽ được theo dõi và gửi trong mail. Ví dụ:
%w(request session environment backtrace)
Mặc định gem sẽ cho chúng ta 6 section:
@kontroller # the controller that caused the error @request # the current request object @exception # the exception that was raised @backtrace # a sanitized version of the exception's backtrace @data # a hash of optional data values that were passed to the notifier @sections # the array of sections to include in the email
- background_sections: Những section sẽ được gửi ngầm, thông qua các ứng dụng như DelayedJob
- email_headers: Tiêu đề cho email, được khai báo theo kiểu Hash of string
- email_format: Định dạng kiểu của file view cho mailer. Ví dụ: :email_format => :html.
Khi ứng dụng được chạy, nếu có bất kì exception được raise, một email sẽ được gửi đến mail mà chúng ta đã config, chứa những thông tin về nơi đã xảy ra lỗi, tương tự như trên console log.
Bạn có thể custom section, thêm các biến cần theo dõi bằng việc tạo một hàm trong ApplicationController:
class ApplicationController < ActionController::Base before_filter :prepare_exception_notifier private def prepare_exception_notifier request.env["exception_notifier.exception_data"] = { :current_user => current_user #Thêm 1 biến current_user cho section, gán nó bằng current_user } end end
Biến current_user được khởi tạo ở đây sẽ được dùng trong các file view.
Hoặc có thể tạo một section mới, khai báo tên của nó trong config section và tạo một file view riêng cho section đó. File view sẽ được đặt trong thư mục ./app/views/exception_notifier/ với kiểu đuôi mặc định là .text.erb. Ví dụ: Chúng ta tạo thêm một section mới, có tên là my_section1, cấu hình cho section mới như sau:
Rails.application.config.middleware.use ExceptionNotification::Rack, :email => { :email_prefix => "[PREFIX] ", :sender_address => %{"notifier" <notifier@example.com>}, :exception_recipients => %w{exceptions@example.com}, :sections => %w{my_section1 my_section2} }
Và file view dành cho section đó sẽ được đặt ở /app/views/exception_notifier/_my_section1.text.erb Lưu ý: Có thể bạn sẽ gặp lỗi không tìm thấy file nếu chỉ sử dụng gem mà không trực tiếp cài đặt vào máy, để xử lý lỗi này, ta chỉ cần thêm config cho custom view trong file khởi tạo của Rails:
ExceptionNotifier::Notifier.prepend_view_path File.join(Rails.root, 'app/views')
Và trong gem config:
Rails.application.config.middleware.use ExceptionNotification::Rack, :email => { :email_prefix => "[PREFIX] ", :sender_address => %{"notifier" <notifier@example.com>}, :exception_recipients => %w{exceptions@example.com}, :sections => %w{my_section1 my_section2} + ExceptionNotifier::Notifier.default_sections }
Việc bắt sự kiện gây lỗi và gửi thông báo cũng có thể thực hiện một cách thủ công bằng cách tạo một hàm gửi notification:
# /app/controllers/application_controller.rb rescue_from Exception, :with => :server_error def server_error(exception) # Whatever code that handles the exception ExceptionNotifier.notify_exception(exception, :env => request.env, :data => {:message => "was doing something wrong"}) end
- :ignore_exceptions: Một mảng string, mặc định là %w{ActiveRecord::RecordNotFound Mongoid::Errors::DocumentNotFound AbstractController::ActionNotFound ActionController::RoutingError ActionController::UnknownFormat}
- :ignore_crawlers: Một mảng string, được sử dụng để loại bỏ các exception gây ra bởi các trình thu nhập thông tin, ví dụ như Googlebot hay bingbot
- :ignore_if: Tùy chọn khai báo kiểu lambda, loại bỏ exception trong một số trường hợp đặc biệt, được tùy biến theo ý người sử dụng.
Các config trên được khai báo trong gem config:
Rails.application.config.middleware.use ExceptionNotification::Rack, :ignore_exceptions => ['ActionView::TemplateError'] + ExceptionNotifier.ignored_exceptions, :ignore_crawlers => %w{Googlebot bingbot}, :ignore_if => ->(env, exception) { exception.message =~ /^Couldn't find Page with ID=/ }, :email => { :email_prefix => "[PREFIX] ", :sender_address => %{"notifier" <notifier@example.com>}, :exception_recipients => %w{exceptions@example.com} }
Tham khảo thêm tại đây