Viết Log ra file trong Ruby on Rails
Bài đăng này đã không được cập nhật trong 7 năm
Lời nói đầu
Việc sử dụng thư viện logger trong Ruby là 1 cách dễ dàng để theo dõi những tương tác của người dùng với hệ thống của chúng ta. Thường thì mỗi khi có 1 tương tác của User với hệ thống thì ở cửa sổ Terminal chúng ta sẽ thấy Log hiện ra, về cơ bản thì Log này sẽ cung cấp cho chúng ta thấy những tương tác với Database và sau đó là việc render ra View, kiểu kiểu như thế này này
Started GET "/" for 127.0.0.1 at 2017-07-28 15:59:13 +0700
ActiveRecord::SchemaMigration Load (0.3ms) SELECT `schema_migrations`.* FROM `schema_migrations`
Processing by StaticPagesController#home as HTML
Rendered support/_slider.html.erb (150.0ms)
Rendered static_pages/home.html.erb within layouts/application (159.3ms)
Rendered layouts/_shim.html.erb (0.3ms)
Rendered layouts/_header.html.erb (8.3ms)
Rendered layouts/_modal.html.erb (0.6ms)
Rendered layouts/_footer.html.erb (1.4ms)
Completed 200 OK in 475ms (Views: 461.8ms | ActiveRecord: 0.0ms)
Dựa vào Status trả về, chúng ta có thể xác định được hệ thống đang chạy đúng không, ví dụ 200 là OK hay gặp lỗi như 404, 400 ... Với môi trường develop thì sau khi chạy rails s, thì log sẽ show ra luôn. Tuy nhiên, để xem log ở với các môi trường khác, như kiểu Staging thì chúng ta sử dụng lệnh sau:
$ tail -f log/staging.log
Các file log này được rails lưu mặc định ở thư mục log và với tên file tương ứng với các môi trường mình sử dụng, development.log, staging.log hay production.log
Tạo file Log khi hệ thống tương tác với bên thứ 3
Nói chung các tương tác của user với hệ thống của chúng ta đều sẽ được Rails lưu lại mặc định ở Log, tuy nhiên khi mà hệ thống tương tác với 1 bên thứ 3 (như request API chẳng hạn) thì Logger của Rails mặc định lại không lưu lại. Và khi việc hệ thống của chúng ta gửi Request sang bên thứ 3 gặp vấn đề, thì sẽ rất khó để tìm ra lỗi gặp phải ở đây. Hay đơn giản, chúng ta cần "bằng chứng" là đã gửi Request sang bên thứ 3 mọi thứ đều chính xác.
Như vây, chúng ta phải tìm cách để ghi lại đoạn log này. Đầu tiên, mình tạo class ApiLog để tạo mới 1 file api.log và lưu trong thư mục log như sau
class ApiLog
def self.debug message = nil
@api_log ||= Logger.new "#{Rails.root}/log/api.log"
@api_log.debug(message) unless message.nil?
end
end
Ở đây, mình gửi Request Http sang bên thứ 3 bằng cách sử dụng Faraday, nên mình sẽ ghi log như sau
def send_request post_data
conn = Faraday.new @url
conn.basic_auth @merchant_id + @service_id, @hashkey
resp = conn.post do |req|
req.headers["content-type"] = "text/xml;charset=Shift_JIS"
req.body = post_data
end
ApiLog.debug resp
resp
end
Với đoạn khai báo ApiLog.debug resp
thì những yêu cầu request sang bên thứ 3 của mình sẽ được lưu lại vào trong log/api.log
Ví dụ cụ thể với hệ thống của mình sẽ kiểu như thế này, gồm có thời gian ghi lại Log và các thông tin như body, header, url ...
D, [2017-07-27T17:28:40.975204 #3398] DEBUG -- : #<Faraday::Response:0x007f2e6365ed78
@on_complete_callbacks=[], @env=#<Faraday::Env @method=:post
@body @url=# @request=#<Faraday::RequestOptions (empty)>
@request_headers={"User-Agent"=>"Faraday v0.9.2", "Authorization"=>"Basic NzIzMzYwMDE6MTQwODMyYjU4YzVhZDYzOTBiNzRhYzY1OTE3NjIyMzFhOTU4ZmM3NQ==", "content-type"=>"text/xml;charset=Shift_JIS"} @ssl=#<Faraday::SSLOptions verify=true>
@response=#<Faraday::Response:0x007f2e6365ed78 ...>
@response_headers={"date"=>"Thu, 27 Jul 2017 10:28:40 GMT", "server"=>"Apache", "set-cookie"=>"JSESSIONID=C1FF1ED1FB119EBCD420B2FB4777C537.f115; Path=/api", "pragma"=>"No-cache", "cache-control"=>"no-cache,no-store,max-age=0", "expires"=>"Thu, 01 Jan 1970 00:00:00 GMT", "content-length"=>"697", "connection"=>"close", "content-type"=>"text/xml;charset=Shift_JIS", "content-language"=>"ja"}
@status=200>>
Tài liệu tham khảo
http://guides.rubyonrails.org/debugging_rails_applications.html
All rights reserved