2011-08-12 37 views
3

我有一些Rake任務產生CSV輸出,我想重定向到一個文件並用其他工具打開,但是當我運行heroku rake foo > foo.csv時,我在輸出中獲得日誌消息(SQL查詢等)。在Heroku上運行Rake任務時,如何將日誌消息保留在STDOUT之外?

我試過Rails.logger = Logger.new('/dev/null')Rails.logger = Logger.new(STDERR)位於Rake任務的頂部,而那些函數在本地是預期的,當我在Heroku上運行任務時,他們沒有任何明顯的效果。

我並不太感到震驚,Heroku會壓縮STDOUT和STDERR在一起,但對我來說,爲什麼發送到/ dev/null不會終止輸出。

任何幫助非常感謝。

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

回答

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初始化;重新分配後不改變原):

在初始化ActiveRecord之前,Heroku的更改可能爲Rails.logger設置了新值。當最終加載ActiveRecord時,它將自己的logger設置爲與Rails.logger(Heroku/stdout之一)相同。當您的任務運行時,它會重新指定Rails.logger,但是對ActiveRecord::Base.logger(唯一最有可能處理SQL日誌)有影響已爲時過晚。

您可能需要重新分配其他一些logger綁定來壓制日誌記錄到STDOUT。 Rails 2部分的rails_log_stdout的init.rb中列出了其他一些可能的位置。

+1

我知道這一點,所以我知道將軍發生了什麼事情的原因,但解決方案是什麼? – camdez

2

我有同樣的問題,雖然我沒有碰到它,直到我改變config/environments/production.rb有這樣的:

config.logger = Logger.new(STDOUT) 

(我這樣做讓我的應用程序會記錄到日誌的Heroku。)

我的修復是這樣的:

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

我面臨同樣的問題,發現下面是一個更方便的解決方法:

添加以下config/environments/production.rb

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

推到Heroku,然後當你運行你的耙子任務時,將LOG_LEVEL="fatal"添加到命令的末尾(替換foofoo.csv用你的東西):

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

log_level設置爲fatal在上面的例子,但它可以是下列任何一項:debug|info|warn|error|fatal。在我們的例子中,使用最高值將意味着什麼,但最致命的錯誤會輸出到csv文件中。

0

只是爲了幫助別人用「新鮮」的Rails項目力推的Heroku:

你需要@馬特·伯克和@傑的回答組合:

這兩行添加到配置/環境/ production.rb

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

,這將建立一個新的標準輸出記錄器,讓您可以輕鬆地控制與LOG_LEVEL環境變量日誌分辨率。

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