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

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

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

根据Rails指南和这个答案 ,我需要做的就是设置它

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我做错了log_formatter ? 当我想要的只是自定义格式时,我宁愿不定义我自己的Logger。


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

我在application.rb设置config.log_formatter并在开发中进行测试,它似乎在一定程度上 Rails.logger.formatter ,因为调用Rails.logger.formatter给了我自定义类。 但这是我在调用Rails.logger.warn("test")看到的行为:

  1. test打印到控制台(后跟换行符)。
  2. 然后输入格式化程序的call方法。
  3. call方法的返回值永远不会打印到控制台。

我认为会发生什么(以及我想要发生的事情):

  1. 输入格式化程序的call方法。
  2. call方法的返回值将打印到控制台。
  3. 没有打印任何其他内容。

我是否误解了格式化程序的工作原理?


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

当我定义了这个:

 def call(severity, time, program_name, message) puts "Checkpoint 1" "Checkpoint 2" end 

并调用Rails.logger.warn("Checkpoint 0") ,我希望看到:

 Checkpoint 1 Checkpiont 2 

但相反,我看到:

 Checkpoint 0 Checkpoint 1 

好的,我们再试一次。

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

  • 你没有说你有什么版本的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 。 我希望得到一条错误消息,因为我没有定义任何路由或控制器或任何东西。 但是由于我奇怪的自定义记录器,我希望所有的日志行基本上都被“Checkpoint 1”和“Checkpoint 2”取代。 事实上,这就是发生的事情。 我的控制台看起来像这样:

  [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 

很明显,自定义'格式化程序'没有做任何有用的事情 - 我强烈建议不要在真正的格式化程序中放置直接的'puts'行。

但我的自定义格式化程序确实被使用,所有日志行都被'格式化'为固定字符串'Checkpoint 2'(最后没有换行符!),而额外的“Checkpoint 1”也放入stdout。

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

事实certificate,我正在将格式化与日志混合,格式化为Rails控制台输出。 我创建了一个GitHub问题和拉取请求 ,使控制台的行为与日志相同。

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

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

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

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