2014-03-12 45 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派上用场,当你在一个繁忙的服务器上查看日志。