在Rails中启用自定义格式化程序

时间:2014-05-31 20:04:23

标签: ruby-on-rails ruby-on-rails-4

我为Rails编写了一个自定义格式化程序:

module Logging
  class GeneralFormatter < Logger::Formatter
    def call(severity, time, program_name, message)
      ...
    end
  end
end

根据Rails guidethis answer,我需要做的就是设置

config.log_formatter = Logging::GeneralFormatter.new

不幸的是,这似乎不起作用 - 我的自定义格式化并没有开始。但是,如果我改为定义它:

module Logging
  class GeneralLogger < ActiveSupport::Logger
    def initialize(*args)
      super(*args)
      @formatter = GeneralFormatter.new
    end
  end
end

然后我可以执行config.logger = Logging::GeneralLogger.new并根据需要格式化我的日志。

设置log_formatter我做错了什么?当我想要的只是自定义格式时,我宁愿不定义自己的Logger。


编辑(回复评论,并从更多挖掘中添加更多细节):

我在config.log_formatter中设置application.rb并在开发中进行测试,并且在调用{{1}时似乎正在中工作给我我的自定义课程。但这是我在调用Rails.logger.formatter时看到的行为:

  1. Rails.logger.warn("test")打印到控制台(后跟换行符)。
  2. 然后输入格式化程序的test方法。
  3. 永远不会将call方法的返回值打印到控制台。
  4. 我认为会发生什么(以及我想要发生的事情):

    1. 输入格式化程序的call方法。
    2. call方法的返回值将打印到控制台。
    3. 没有打印任何其他内容。
    4. 我是否误解了格式化程序的工作原理?


      再次编辑(提供更清晰的示例):

      当我定义了这个:

      call

      并致电def call(severity, time, program_name, message) puts "Checkpoint 1" "Checkpoint 2" end ,我希望看到:

      Rails.logger.warn("Checkpoint 0")

      但我看到了:

      Checkpoint 1
      Checkpiont 2
      

3 个答案:

答案 0 :(得分:3)

好的,让我们再试一次。

我实际上没有答案 - 相反,我无法重现您的问题。我会告诉你我采取的步骤和我所看到的步骤,也许你将能够与你所做的相比较,看看它与众不同之处。

  • 你没有说出你的Rails版本,我从最新的4.1.1开始。构建了一个全新的应用程序rails new logtest

./lib/custom_formatter.rb添加了一个如下所示的文件:

class CustomFormatter < Logger::Formatter
  def call(severity, time, program_name, message)
    # I think it makes no sense to have a raw `puts`
    # in a log formatter, but I'll leave it in to
    # copy you. Almost certainly a bad idea though. 
    # commented out. 
    puts "Checkpoint 1"
    return "Checkpoint 2"
  end
end

将此添加到我现有的config/application.rb

require 'custom_formatter'
config.log_formatter = CustomFormatter.new

现在,我使用rails server启动应用程序,然后访问http://localhost:3000/test。我希望得到一条错误信息,因为我还没有定义任何路线或控制器或任何东西。但由于我的奇怪的自定义记录器,我希望所有的日志行基本上被&#34; Checkpoint 1&#34;和&#34;检查站2&#34;。确实发生了什么。我的控制台看起来像这样:

  [2014-06-03 18:22:49] INFO  WEBrick 1.3.1
  [2014-06-03 18:22:49] INFO  ruby 1.9.3 (2013-02-22) [x86_64-darwin12.2.1]
  [2014-06-03 18:22:49] INFO  WEBrick::HTTPServer#start: pid=57113 port=3000
  Checkpoint 1
  Checkpoint 2Checkpoint 1
  Checkpoint 1
  Checkpoint 2Checkpoint 1
  Checkpoint 1
  Checkpoint 2Checkpoint 1
  Checkpoint 1
  Checkpoint 2Checkpoint 1
  Checkpoint 1
  Checkpoint 2Checkpoint 1
  Checkpoint 1
  Checkpoint 2Checkpoint 1
  Checkpoint 1
  Checkpoint 2Checkpoint 1

我的development.log看起来像这样:

  Checkpoint 2Checkpoint 2Checkpoint 2Checkpoint 2Checkpoint 2Checkpoint 2Checkpoint 2

很明显,自定义&#39;格式化程序&#39;并没有做任何有用的事情 - 我强烈建议不要直接放置&#39; put&#39;在一个真正的格式化程序中。

但是我的自定义格式化程序确实被使用了,所有日志行都被格式化了#39;作为固定字符串&#39; Checkpoint 2&#39; (最后没有换行!),以及附加的&#34; Checkpoint 1&#34;也是stdout。

所以,如果我尝试按照你说的那样做,你的问题不能通过你给出的步骤重现,我不会这样做。有你的问题。所以,这确实是调试工作的方式,令人沮丧!我建议你按照我的步骤在上面创建一个测试应用程序,看看它是否适合你。然后,您必须将您的实际应用与该小测试应用进行比较,并找出它的不同之处,以便在您的实际应用中显示问题。一种常见的方法是复制您的实际应用程序,并开始删除所有可能的内容,以获得仍然可以解决问题的最简单的应用程序。在这样做的过程中,您可以自己找出问题的原因 - 但如果您不这样做,您可以将您的裸骨演示应用程序提供给其他试图帮助您的人,他们可以也许弄清楚是什么导致了这个问题。

答案 1 :(得分:3)

事实证明,我正在将格式化与日志混合,格式化为Rails控制台输出。我已创建了GitHub Issuepull request,以使控制台的行为与日志相同。

答案 2 :(得分:0)

如果您输入格式化程序的调用方法,那么显然您的自定义格式化程序正在调用,对吧?

您实际上还没有向我们提供格式化程序实现的来源,但格式化程序似乎很可能不会按照您的想法工作,如果它被调用但没有做您想做的事情。我实际上并不是格式化程序如何工作的专家,但是可能会找到一些已知的工作格式化程序实现的示例,可能在rails源代码中,看看它们与您的不同之处?

你说格式化程序#call的返回值是打印到控制台的 - 这是否意味着它毕竟正在工作?你还有什么期望?

(格式化程序无法控制发送日志的位置,在Rails的开发中我认为它已发送到控制台和开发日志文件。可以更改,但不能使用自定义格式化程序)