将vs记录器置于Rails Rake任务中


108

在rake任务中,如果使用puts命令,则会在控制台上看到输出。但是,当在生产环境中部署应用程序时,我不会在日志文件中看到该消息。

但是,如果我说Rails.logger.info,那么在开发模式下,控制台上什么也看不到。我需要去日志文件并尾随它。

理想情况下,我想使用Rails.logger.info并在rake任务中的开发模式下,还将logger的输出发送到控制台。

有办法实现吗?

Answers:


57

将其放入application.rb或放入rake任务初始化代码

if defined?(Rails) && (Rails.env == 'development')
  Rails.logger = Logger.new(STDOUT)
end

这是Rails 3代码。请注意,这将覆盖记录到development.log。如果你想同时STDOUTdevelopment.log你需要的包装功能。

如果仅在Rails控制台中希望这种行为,请将相同的代码块放入中~/.irbrc


26
仅仅放入Rails.logger = Logger.new(STDOUT)development.rb 会更容易吗?
ghempton

对于rails 2,请将其放在您的development.rb中:config.logger = Logger.new(STDOUT)
jsarma

38

您可以创建一个新的rake任务以使其正常工作。

desc "switch logger to stdout"
task :to_stdout => [:environment] do
 Rails.logger = Logger.new(STDOUT)
end

这样,当您执行rake任务时,您可以先添加to_stdout以获得stdout日志消息,也可以不包括它以将消息发送到默认日志文件

rake to_stdout some_task

11

瑞克任务由用户在命令行上运行。他们需要立即知道的所有信息(“已处理的5行”)都应该在终端上输出puts

后代需要保留的所有内容(“将警告电子邮件发送到jsmith@example.com”)都应发送到Rails.logger


17
用cron运行rake任务并不少见。
Johannes Gorset

2
真正。如果您希望在cron作业完成时将日志消息通过电子邮件发送给您,请将其吐出到$ stdout或$ stderr。
乔纳森·朱利安

10

我会说使用Rails.logger.info是必经之路。

您将无法在服务器控制台中看到它,因为它不会通过服务器运行。只要打开一个新的控制台和tail -f日志文件,它就可以解决问题。

许多用户都知道UNIX®命令“ tail”,该命令可用于显示大文件的最后几行。这对于查看日志文件等很有用。

在某些情况下甚至更有用的是'tail'命令的'-f'参数。这会使tail尾随其后的文件输出。最初,响应本身将与对“ tail”的响应相同-将显示文件的最后几行。但是,该命令不会返回到提示,而是继续“关注”文件。将其他行添加到文件后,它们将显示在终端上。这对于观看日志文件或随时间推移可能附加的任何其他文件非常有用。输入“ man tail”以获取有关此选项和其他尾部选项的更多详细信息。

通过


但是在本地计算机上工作时感觉不太舒服,因为在调用任务的同一窗口中看不到输出。特别是如果您没有大屏幕可以同时容纳多个窗口。
Tomas Markauskas,2010年

10
更好的方法是使用tailf“它类似于tail -f,但是当文件不增长时不访问该文件”(来自联机帮助页)。它也更短
MBO 2010年

@tomas为什么不最小化服务器日志控制台,而只有一个运行tail-f的控制台?无论如何,这都不是一个真正的问题……我的运行就像跟踪我的应用程序中的8个控制台一样,当您在系统的特定部分上工作时,只需在选项卡之间切换就可以了,没什么大不了的事
marcgg 2010年

@mbo nice :)哈拉斯,它看起来好像在我的机器上不可用(mac os @ leopard)
marcgg

1
@marcgg:我没有“服务器控制台”(我使用的是passenger),但是问题是关于rake任务,如果您从一个终端窗口运行一个任务,那么在该窗口中记录程序中什么也看不到。您必须使用development.log拥有另一个窗口才能看到输出。理想情况下,我会以某种方式将stdout作为另一个输出流添加到Rails.logger,但不删除原始的流。
Tomas Markauskas,2010年

9

对于Rails 4及更高版本,您可以使用Logger broadcast

如果要在开发模式下同时获取rake任务的STDOUT和文件日志记录,可以将此代码添加到config/environments/development.rb

  if File.basename($0) == 'rake'
    # http://stackoverflow.com/questions/2246141/puts-vs-logger-in-rails-rake-tasks
    log_file     = Rails.root.join("log", "#{Rails.env}.log")
    Rails.logger = ActiveSupport::Logger.new(log_file)
    Rails.logger.extend(ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT)))
  end

测试

这是一个小的Rake任务,用于测试上述代码:

# lib/tasks/stdout_and_log.rake
namespace :stdout_and_log do
  desc "Test if Rails.logger outputs to STDOUT and log file"
  task :test => :environment do
    puts "HELLO FROM PUTS"
    Rails.logger.info "HELLO FROM LOGGER"
  end
end

运行rake stdout_and_log:test输出

HELLO FROM PUTS
HELLO FROM LOGGER

HELLO FROM LOGGER

已添加到中log/development.log

运行rake stdout_and_log:test RAILS_ENV=production输出

HELLO FROM PUTS

HELLO FROM LOGGER

已添加到中log/production.log


在Rails 5中,该basename($0) == 'rake'技巧不再起作用,因为rails命令本身会运行rake。我很想为它找一个好的替代品,而不仅仅取决于设置任务broadcast。(至少该部分仍然可以正常工作。)
布伦特皇家-戈登

@ BrentRoyal-Gordon无需在开发中使用此条件,您只需将代码添加到Rakefile项目的根目录下
Mauricio Pasquier Juan

4

如何创建一个应用程序帮助程序来检测正在运行的环境并做正确的事情?

def output_debug(info)
   if RAILS_ENV == "development"
      puts info
   else
      logger.info info
   end
end

然后调用output_debug而不是puts或logger.info


5
我认为这不是一个好主意。Rails记录器本来应该是可配置的,但是除了使用该可配置性之外,您还可以在此处堆叠更多的层。
Sijmen Mulder 2012年

是的,这不是一个好主意,因为每次您要记录某些内容时都会进行相同的检查。
furiabhavesh


2

使用“&”执行后台作业,然后打开脚本/控制台或其他命令。这样,您可以在同一窗口中运行多个命令。

tail -f log/development.log &
script/console
Loading development environment (Rails 2.3.5)
>> Product.all
2011-03-10 11:56:00 18062 DEBUG  Product Load (6.0ms)  SELECT * FROM "products"
[<Product.1>,<Product.2>]

note备注当有大量日志输出时,可能很快变得草率。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.