rails4中的自定义记录器?

jro*_*ind 2 logging ruby-on-rails

看起来Rails4的记录器与Rails3不同,它最终支持自定义格式化程序,就像ruby stdlib记录器一样.

Rails.logger.formatter  # => #<ActiveSupport::Logger::SimpleFormatter:0x007ff81757d890 @datetime_format=nil>
Rails.logger.formatter = SomeFormatterClass
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试给它一个格式化程序类,这对于stdlib Logger格式化程序来说已经足够了:

[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'
Run Code Online (Sandbox Code Playgroud)

有谁知道,自定义格式化程序实际上是Rails4支持的功能吗?您是如何在任何地方记录的?

jro*_*ind 5

回答我自己的问题,我已经弄明白了.

Rails4提供了一个配置变量config.log_formatter.你可能会在config/application.rb其他应用程序配置中设置它.

您应该将其设置为实现stdlib Logger Formatter接口的对象:基本上,您必须提供一个call(severity, time, progname, msg)返回格式化日志行的方法.

请注意,您将其设置为对象,而不是类名,例如:

config.log_formatter = MyFormatter.new
Run Code Online (Sandbox Code Playgroud)

你应该尝试直接设置Rails.logger.formatter - Rails的期待您通过配置设置,并做一些棘手的东西使用Rails,使您的格式,并记录仪正常工作时使用的配置.您可以config.log_formatterRails源代码中看到,以及确实使用.(感谢github并且它是非常棒的代码搜索和显示ui,我是如何跟踪它并找出存在的config.log_formatter)

在Rails4,你应该不会需要猴子补丁的Rails的任何部分只是使用自定义日志格式,只需使用config.log_formatter来代替.(在Rails3中,您确实需要对其中一个或另一个进行修补以获得自定义日志格式).


Dan*_*fan 5

如果它对其他人有帮助,在 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
Run Code Online (Sandbox Code Playgroud)

为了实现这一点:

# 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
Run Code Online (Sandbox Code Playgroud)

一些注意事项:

  • if语句防止没有消息的日志条目以及记录资产文件服务的日志消息。
  • + "\r\n"在行尾添加了一个 CR+LF,因此它在 Rails 服务器控制台中仍然具有一定程度的可读性。
  • 我添加是app因为我在许多应用程序之间共享一个日志文件。您可以在仅使用一个 Rails 应用程序的系统中删除它。
  • 我发现process_id当您在繁忙的服务器上查看日志时非常有用。