Quản lý user exception với RayGun

raygun.jpg

I. Mở đầu

Xin chào các bạn (lay2)

Đến hẹn lại lên, hôm nay tôi sẽ trình bày một vấn đề mà Developer đã nhẵn mặt với nó - Error

Vâng, đối với Developer, việc gặp phải Bug khi chạy sản phẩm là điều xảy ra như cơm bữa. Dựa lỗi gặp phải, ta có thể sửa, cải tiến để sản phẩm mình hoàn thiện hơn.

Nhưng nếu người gặp lỗi đó là User thì sao?

Nếu là tôi, khi dùng một sản phẩm mà cứ lỗi lên lỗi xuống thì ...thôi, bỏ luôn để kiếm cái khác, cũng chả buồn feedback luôn (yaoming).

Vấn đề ở đây là, Developer sẽ không biết sản phẩm của mình khi User sử dụng sẽ gặp phải lỗi gì, ở đâu, lúc nào, để mà sửa. Lượng người dùng cứ dần sụt giảm mà đếch hiểu tại sao (╯°□°)╯︵ ┻━┻

Việc fixbug trên production đã bị phụ thuộc vào feedback từ User.

Nhưng đừng lo, hôm nay tôi sẽ giới thiệu tới các bạn một anh chàng mạnh mẽ (có trả phí) giúp giải quyết vấn đề này - súng ca Raygun (dance2)

Raygun được đưa ra vào khoảng đầu năm 2013, công ty ban đầu có tên là Mindscape.

Họ muốn tìm một cách tốt hơn để xử lý bug trên production và thế là Raygun ra đời.

Raygun có 2 services chính:

  • Raygun Crash Reporting: Giúp theo dõi hoạt động của app, gửi thông báo và nội dung lỗi gặp phải khi sử dụng sản phẩm tới Raygun server. Dashboard hiển thị thống kê chi tiết, nhóm các error lại, ...

  • Raygun Pulse: Kiểu giống Google Analytics, theo dõi hoạt động của app, báo cáo về performance, user info, location,...

II. Demo

Các công việc sẽ làm:

  • Khởi tạo web app, add các gem cần thiết.
  • Đăng ký sử dụng Raygun.
  • Config để tích hợp Raygun trong app.
  • Custom raygun.

Công cụ sử dụng:

  • Rails 4.2.1
  • Ruby 2.1.4

Let's start (honho)

1. Khởi tạo

Khởi tạo rails app bằng lệnh

rails new gunner

Generate controller để xử lý, ta tạm gọi là PagesController

rails g controller pages index

Chỉnh routes một chút

# config/routes.rb
root "pages#index"

Tiếp đến ta sẽ add thêm gem cho app và chạy bundle install để cài đặt.

gem "raygun4ruby"

Raygun có tính phí, tuy nhiên, họ cũng cung cấp gói free trier trong vòng 30 ngày để thử máy.

Ta tạo tài khoản và truy cập: https://app.raygun.io/s/createapp?gDisplay=True để đăng ký

signup1.png Điền tên Application

signup2.png Lựa chọn ngôn ngữ

Sau khi chọn xong, Raygun sẽ cung cấp cho ta Application API Key dùng để cài đặt trên app, các bạn nhớ lưu lại.

Tiếp theo, ta tiến hành generate Raygun config trên app bằng lệnh

rails g raygun:install APP_API_KEY

trong đó APP_API_KEY chính là đoạn mã mà Raygun cung cấp khi ta đăng ký ở trên.

Mặc định, Raygun sẽ không gửi dữ liệu tới servers ở ENV Development, vậy nên ta cần config lại một chút

config/initializers/raygun.rb

config.enable_reporting = true

Setup đơn giản vậy thôi (dance2).

2. Crash Reporting

Để test xem đã hoạt động chưa, ta chạy lệnh

rake raygun:test

Trên terminal sẽ hiện ra dòng

Success! Now go check your Raygun.io Dashboard

Mở Dashboard trên Raygun ra kiểm tra

success.png

Message lúc này đã được gửi thành công tới Raygun Server, vậy là ok rồi (honho)

Raise Errors

Bây giờ ta bắt tay vào việc gửi error exception của app tới Raygun khi gặp lỗi. Ở method index trong controller, ta code ba lăng nhăng vào để nó raise ra lỗi

# pages_controller.rb
def index
  kappa_kappa
end

Mở rails server và truy cập tới trang chủ, nó sẽ render ra trang báo lỗi như bình thường. Tuy nhiên, nếu để ý kỹ 1 chút, ở trên Terminal của ta có hiện ra dòng

[Raygun] Tracking Exception...

Có nghĩa là errors catch được đã gửi tới Raygun server

Ngó sang Dashboard sẽ thấy hàng về (thời gian, log liếc đầy đủ luôn) (dance2) errors1.png

Trong trường hợp phía Client có các params là dữ liệu "nhạy cảm" (vd: password) (hihi), ta có thể bỏ qua nó bằng bộ lọc filter_parameters

# config/initializers/raygun.rb

config.filter_parameters = [:password]

Custom data

Errors gửi lên Raygun server không chỉ là log giống như ta nhìn thấy trên Terminal, ta hoàn toàn có thể custom, gửi thêm data nếu cần thiết.

Giả sử ta có 1 exception kinh điển, chia 1 số cho 0 (yaoming)

def index
  begin
    1 / 0
  rescue Exception => e
    Raygun.track_exception(e, custom_data: {my: 'I can do zero division. Feels good man'})
  end
end

Mở tab custom data của lỗi này trên Dashboard sẽ thấy message đi kèm mà ta vừa set.

custom.png

Ignore errors

Một số exception bạn muốn bỏ qua, không gửi tới Raygun nếu gặp phải nó. Ví dụ ta muốn ignore lỗi chia cho 0 ở phía trên:

# config/initializers/raygun.rb

config.ignore << ['ZeroDivisionError']

Reload lại trang, sẽ không thấy dòng

[Raygun] Tracking Exception...

hiển thị trên terminal nữa. Đương nhiên, check Dashboard cũng không thấy gì cả.

Ở đây lưu ý một chút, là Raygun tự động ignore một số exception sau:

  • ActiveRecord::RecordNotFound
  • ActionController::RoutingError
  • ActionController::InvalidAuthenticityToken
  • ActionDispatch::ParamsParser::ParseError
  • CGI::Session::CookieStore::TamperedWithCookie
  • ActionController::UnknownAction
  • AbstractController::ActionNotFound
  • Mongoid::Errors::DocumentNotFound

Nếu bạn muốn track chúng, dùng lệnh delete khỏi hash đấy là xong

# config/initializers/raygun.rb

config.ignore.delete("ActiveRecord::RecordNotFound")

3. Pulse

Cài đặt cái này còn ez hơn nhiều, bạn thêm đoan script sau vào layout

# views/layouts/application.html.erb

<script type="text/javascript">
  !function(a,b,c,d,e,f,g){a.RaygunObject=e,a[e]=a[e]||function(){
  (a[e].o=a[e].o||[]).push(arguments)},f=b.createElement(c),g=b.getElementsByTagName(c)[0],
  f.async=1,f.src=d,g.parentNode.insertBefore(f,g)}(window,document,"script","//cdn.raygun.io/raygun4js/raygun.min.js","rg4js");

  rg4js('apiKey', APP_API_KEY);
  rg4js('enablePulse', true);
  rg4js('enableCrashReporting', false);
</script>

APP_API_KEY vẫn là cái Raygun cung cấp ban đầu.

Reload lại trang và check mục Pulse trong Dashboard pulse.png

GGWP

Source code

Github: https://github.com/NguyenTanDuc/gunner

Nguồn tham khảo