0

いくつかのバックグラウンド ジョブに遅延ジョブを使用する Rails 3.2 アプリ (Windows Server 2008 R2 上の Ruby 1.9.2p290) が動作しています。最近、Rails のデフォルトのロギングを log4r に置き換えましたが、Rails アプリでは問題なく動作しています。ただし、rake jobs:workタスクを開始すると、アウトプッターが nil であるというエラーが表示されます。

ジョブワーカーの開始
レーキが中止されました!
TypeError: Outputter の種類が予期されていましたが、NilClass を取得しました
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/log4r-1.1.10/lib/log4r/logger.rb:120:in `each'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/log4r-1.1.10/lib/log4r/logger.rb:120:「追加」
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/delayed_job-4.0.0/lib/delayed/worker.rb:248:in `say'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/delayed_job-4.0.0/lib/delayed/worker.rb:147: in `start'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/delayed_job-4.0.0/lib/delayed/tasks.rb:9:in `ブロック (2 レベル) in '
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/task.rb:240:in `call'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/task.rb:240:in `block in execute'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/task.rb:235:in `each'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/task.rb:235:in `execute'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/task.rb:179:in `block in invoke_with_call_chain'
F:/web-shared/Ruby192/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/task.rb:172:in `invoke_with_call_chain'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/task.rb:165:in `invoke'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:150:in `invoke_task'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:106:in `block (2レベル) in top_level
'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:106:in `each'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:106:in `block in top_level'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:115:in `run_with_threads'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:100:in `トップレベル'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:78:in `block in run'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:176:in `standard_exception_handling'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/lib/rake/application.rb:75: in `run'
F:/web-shared/Ruby192/lib/ruby/gems/1.9.1/gems/rake-10.2.2/bin/rake:33:in `'
F:/web-shared/Ruby192/bin/rake:19:in `load'
F:/web-shared/Ruby192/bin/rake:19:in `'
タスク: TOP => 仕事:仕事

遅延ジョブでlog4rを使用して成功した人はいますか? いくつかのポインターを使用できます。Google や DuckDuckGo で検索しても何も見つかりませんでした。

config/application.rbスニペットは次のとおりです。

require File.expand_path('../boot', __FILE__)

require 'erb'
require 'rails/all'

# log4r
require 'log4r'
require 'log4r/yamlconfigurator'
require 'log4r/outputter/datefileoutputter'
require 'log4r/outputter/consoleoutputters'
include Log4r

...

class Application < Rails::Application

...

  # assign log4r's logger as rails' logger.
  log4r_config = YAML.load(ERB.new(File.read(File.join(File.dirname(__FILE__), 'log4r.yml'))).result)
  log4r_config['ENV'] = Rails.env
  log4r_config['APPNAME'] = Rails.application.class.parent_name
  YamlConfigurator.decode_yaml(log4r_config['log4r_config'])
  config.logger = Log4r::Logger[Rails.env]
  ActiveRecord::Base.logger = Log4r::Logger[Rails.env]
end

config/log4r.ymlファイルは次のとおりです。

log4r_config:
  # define all loggers ...
  loggers:
  - name: production
    level: WARN
    trace: 'false'
    outputters:
      - datefile_production
      - console_production
  - name: development
    level: DEBUG
    trace: 'true'
    outputters:
      - datefile_development
      - console_development
  - name: test
    level: DEBUG
    trace: 'true'
    outputters:
      - datefile_test
      - console_test

  # define all outputters (incl. formatters)
  outputters:
  - type: DateFileOutputter
    name: datefile_production
    dirname: "<%= File.join(Rails.root, 'log') %>"
    filename: "production.log"
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%p\t%d\t%X{:remote_ip}\t%X{:user}\t%X{:controller}\t%X{:action}\t%l\t%m'
      type: PatternFormatter
  - type: DateFileOutputter
    name: datefile_development
    dirname: "<%= File.join(Rails.root, 'log') %>"
    filename: "development.log"
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%p\t%d\t%X{:remote_ip}\t%X{:user}\t%X{:controller}\t%X{:action}\t%l\t%m'
      type: PatternFormatter
  - type: DateFileOutputter
    name: datefile_test
    dirname: "<%= File.join(Rails.root, 'log') %>"
    filename: "test.log"
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%p\t%d\t%X{:remote_ip}\t%X{:user}\t%X{:controller}\t%X{:action}\t%l\t%m'
      type: PatternFormatter
  - type: StdoutOutputter
    name: console_production
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%p\t%d\t%l\t%m'
      type: PatternFormatter
  - type: StdoutOutputter
    name: console_development
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%p\t%d\t%X{:remote_ip}\t%X{:user}\t%X{:controller}\t%X{:action}\t%l\t%m'
      type: PatternFormatter
  - type: StdoutOutputter
    name: console_test
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%p\t%d\t%X{:remote_ip}\t%X{:user}\t%X{:controller}\t%X{:action}\t%l\t%m'
      type: PatternFormatter

アップデート

デバッガーで rake タスクを実行した後、何が起こっているのかがわかりました。

Delayed::Worker( delayed_job/lib/delayed/worker.rb 行 248 ) は、次のようなロガーの add メソッドを介してメッセージをログに記録しています。

logger.add level, "#{Time.now.strftime('%FT%T%z')}: #{text}" if logger

Loggerこれは、Ruby のクラスに対して有効で正しいものです。 Logger.html#method-i-add を参照してください。ただし、log4r を使用すると、アウトプッターを追加しようとするLog4r::Logger.add( log4r/lib/log4r/logger.rb 行 119 ) に解決されます。

なぜこれが起こっているのか、または解決策が何であるかはわかりません。

4

2 に答える 2

1

現在、delayed_jobs 4.0.1 gem に更新できます。これにより、この問題が解決されます。

于 2014-04-29T17:33:34.280 に答える
0

(この問題に関する元のコメントについては、 blog.mmlac.comを参照してください。)

問題は、DelayedJob がロガーが Rails::Logger であることを期待し、log4r がサポートしていない呼び出しを行うことです。

この記事では、Log4r::Logger を使用するように logger 変数が上書きされますが、これは意図した .add 呼び出しをサポートしていません。Java とは異なり、使用するロガー クラスを決定するパッケージや、さまざまなロガーを標準インターフェイスに統合する slf4j はありません。

この問題に対する簡単な解決策はありません。一方では、delayedJob の影響を受ける部分を上書きできます。一方、delayedJob が Rails を実行している場合、つまりカスタム環境を使用することで、log4r のロードを防ぐことができます。

  • 発達
  • 製造
  • 遅延ジョブ

また、これはどこでも動作することが保証されているわけではありません (rails env == “production” をチェックするものには問題があります)。

もう 1 つの方法は、環境変数を使用して、application.rb でそれらを確認することです。

if (ENV["log4rlogger"] == "true") config.logger = Log4r::Logger["rails"]
于 2014-03-31T20:30:29.307 に答える