2014-03-12 47 views
1

它看起來像Rails4的記錄器,不像Rails3的,最終支持自定義格式化程序,如紅寶石stdlib記錄器再次。在rails4中自定義記錄器?

Rails.logger.formatter # => #<ActiveSupport::Logger::SimpleFormatter:0x007ff81757d890 @datetime_format=nil> 
Rails.logger.formatter = SomeFormatterClass 

然而,當我嘗試給它一個格式化類,就足以STDLIB記錄儀格式:

[2014-03-12 16:23:27] ERROR NoMethodError: undefined method `tagged' for #<FormattedRailsLoggerFormatter:0x007fd816545ad8> 
/Users/jrochkind/.gem/ruby/1.9.3/gems/activesupport-4.0.3/lib/active_support/tagged_logging.rb:67:in `tagged' 
/Users/jrochkind/.gem/ruby/1.9.3/gems/railties-4.0.3/lib/rails/rack/logger.rb:20:in `call' 

有誰知道,是自定義格式實際上Rails4的支持功能?你是如何在任何地方記錄下來的?

+0

你檢查了這個http://stackoverflow.com/questions/18176447/undefined-method-tagged-for-formatter-error-after-rails-4-upgrade? – MikeZ

+0

我沒有找到你指出它之前提到的StackOverflow,但我沒有發現它也回答了我的問題。 – jrochkind

回答

5

回答我自己的問題,我已經想通了。

Rails4提供了一個配置變量,config.log_formatter。您可能會將其設置在config/application.rb以及其他應用程序配置中。

您應該將它設置爲實現stdlib Logger Formatter接口的對象:基本上,您必須提供一個方法call(severity, time, progname, msg),它返回格式化的日誌行。

注意將其設置爲一個對象,而不是類名稱,例如:

config.log_formatter = MyFormatter.new 

你應該嘗試直接設置Rails.logger.formatter - Rails的期待您通過配置設置,並做一些棘手的事情,以使您的格式化器和記錄器在使用配置時可以正常使用Rails。你可以看到,以及看到確實使用config.log_formatter,在Rails source code here。 (感謝GitHub上和它的真棒代碼搜索和顯示界面,是我如何跟蹤下來,並計算出的config.log_formatter存在)

在Rails4,你應該需要猴子補丁的Rails的任何部分剛使用自定義日誌格式化程序,只需使用config.log_formatter。 (在Rails3中,你確實需要對其中一個或另一個進行猴子補丁以獲得自定義日誌格式)。

+0

你有什麼想法,爲什麼設置'config.log_formatter'不適合我?看到我的問題[這裏](http://stackoverflow.com/questions/23974180/enabling-a-custom-formatter-in-rails)。 – JacobEvelyn

2

在情況下,它可以幫助別人,用Rails 4.2.6和Ruby 2.3.0,這是對我工作:

# config/application.rb 
module MyRailsApp 
    class Application < Rails::Application 
    require 'my_log_formatter' 
    ... 
    # Custom log formatter that uses JSON 
    config.log_formatter = MyLogFormatter.new 
    end 
end 

要做到這一點:

# lib/my_log_formatter.rb 
class MyLogFormatter < ActiveSupport::Logger::SimpleFormatter 
    def call(severity, timestamp, progname, message) 
    if message.present? && message.exclude?('Started GET "/assets') 
     { 
      app: Rails.application.class.parent_name, 
      process_id: Process.pid, 
      level: severity, 
      time: timestamp, 
      progname: progname, 
      message: message 
     }.to_json + "\r\n" 
    else 
     '' 
    end 
    end 
end 

的一些注意事項:

  • if語句阻止沒有消息的日誌條目,並記錄日誌服務資產文件的消息。
  • + "\r\n"在該行的末尾添加了一個CR + LF,因此它在rails服務器控制檯中仍然有點人類可讀。
  • 我加了app,因爲我在許多應用程序中共享一個日誌文件。你可以在只使用一個Rails應用程序的系統中刪除它。
  • 我發現process_id派上用場,當你在一個繁忙的服務器上查看日誌。