在Heroku上运行Rake任务时,如何将日志消息保留在STDOUT之外?

时间:2011-08-12 02:36:35

标签: ruby-on-rails heroku rake

我有一些生成CSV输出的Rake任务,我想将其重定向到文件并使用其他工具打开,但是当我运行heroku rake foo > foo.csv时,我会收到日志消息(SQL查询等)输出

我在Rake任务的顶部尝试了Rails.logger = Logger.new('/dev/null')Rails.logger = Logger.new(STDERR),当这些在本地运行时,当我在Heroku上运行任务时,它们没有任何明显的效果。< / p>

Heroku将STDOUT和STDERR压在一起我并不感到震惊,但对我来说,为什么发送到/ dev / null不会导致输出无效。

非常感谢任何帮助。

Rails v3.0.0,Heroku bamboo-ree-1.8.7 stack,rake 0.9.2。

5 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,但在我更改config/environments/production.rb之前我没有遇到过这个问题:

  config.logger = Logger.new(STDOUT)

(我这样做是为了让我的应用程序登录到heroku日志。)

我的解决方法是:

config.logger = Logger.new(STDOUT) unless 'rake' == File.basename($0)

答案 1 :(得分:1)

来自Heroku | Dev Center | Logging

  

当推送Rails应用时,我们会自动将rails_log_stdout插件安装到应用中,该插件会将日志重定向到stdout

我认为Heroku包括(在通过git push命令发送的输出中)关于此的通知(以及另一个添加:用于提供静态/ public内容,如果我没记错的话)。您可能只会看到某些类型推送的通知(完整的slug重建?)。我记得当我最近将一个新应用程序推送到Bamboo / MRI-1.9.2堆栈时看到它,但我不认为每次将更改推送到应用程序的代码时都会收到消息(可能会向Gemfile添加一个新的gem)足以触发吗?)。


多个Rails子系统保持自己的logger绑定(独立绑定的值通常从Rails.logger初始化;重新分配后者不会改变前者):

Heroku的更改可能会在Rails.logger初始化之前为ActiveRecord设置新值。最终加载ActiveRecord时,它会将自己的logger设置为与Rails.logger(Heroku / stdout)相同。当您的任务运行时,它会重新分配Rails.logger,但现在对ActiveRecord::Base.logger(唯一最有可能处理SQL日志)的任何影响为时已晚。

您可能需要重新分配其他一些logger绑定来压制转到STDOUT的日志记录。其他一些可能的位置列在Rails 2部分的rails_log_stdout的init.rb中。

答案 2 :(得分:1)

我遇到了同样的问题,发现以下是更方便的解决方法:

将以下内容添加到config/environments/production.rb

config.logger.level = Logger.const_get(ENV['LOG_LEVEL'] ? ENV['LOG_LEVEL'].upcase : 'INFO')

推送到Heroku,然后当你运行rake任务时,将LOG_LEVEL="fatal" 添加到命令的结尾(用你的东西替换foofoo.csv

heroku run rake foo LOG_LEVEL="fatal" > foo.csv

我在上面的示例中将log_level设置为fatal,但它可以是以下任何一种:debug|info|warn|error|fatal。在我们的例子中,使用最高值只会将最致命的错误输出到csv文件中。

答案 3 :(得分:0)

只是为了帮助任何一个“新鲜”的Rails项目推向Heroku:

你需要结合@Matt Burke和@ Hengjie的回答:

将这两行添加到 config / environments / production.rb

config.logger = Logger.new(STDOUT)
config.logger.level = Logger.const_get(ENV['LOG_LEVEL'] ? ENV['LOG_LEVEL'].upcase : 'INFO')

这将设置一个新的STDOUT记录器,并允许您使用LOG_LEVEL环境变量轻松控制日志分辨率。

答案 4 :(得分:0)

我通过对production.rb的以下更改解决了这个问题:

if 'rake' == File.basename($0)
  ActiveRecord::Base.logger = Logger.new('rake.log', 'daily')
end

我想我们也可以忽略输出

if 'rake' == File.basename($0)
  ActiveRecord::Base.logger = Logger.new('/dev/null')
end