使用延迟作业的log4r出现错误



我有一个工作的Rails 3.2应用程序(Windows Server 2008 R2上的Ruby 1.9.2p290),它为几个后台作业使用延迟作业。我最近用log4r取代了Rails的默认日志记录,它在Rails应用程序中工作得很好。然而,当我启动rake jobs:work任务时,我得到一个错误,抱怨nil输出:

<>之前上岗工人rake流产!TypeError:期望的输出类型,得到NilClassF:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/log4r-1.1.10/lib/log4r/记录器。rb: 120:"每一个"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/log4r-1.1.10/lib/log4r/记录器。rb: 120:在"添加"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/delayed_job-4.0.0/lib/延期/工人。rb: 248:在"说"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/delayed_job-4.0.0/lib/延期/工人。rb: 147:在"开始"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/delayed_job-4.0.0/lib/延期/任务。Rb:9:在'块(2级)在'F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/lib/rake任务。rb: 240:在"调用"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/lib/rake任务。在' block in execute'F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/lib/rake任务。rb: 235:"每一个"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/lib/rake任务。rb: 235:在"执行"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/lib/rake任务。在' block in invoke_with_call_chain'F:/web-shared Ruby192/lib/ruby/1.9.1/班长。rb: 201:"mon_synchronize"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/lib/rake任务。rb: 172:"invoke_with_call_chain"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/lib/rake任务。rb: 165:在"调用"F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。rb: 150:"invoke_task"F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。Rb:106:在'块(2级)在top_level'F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。rb: 106:"每一个"F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。在' block in top_level'F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。rb: 115:"run_with_threads"F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。rb: 100:"top_level"F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。78:在'盖帽在运行'F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。rb: 176:"standard_exception_handling"F:/web-shared/Ruby192/lib/ruby/珠宝/1.9.1/宝石/rake-10.2.2/lib/耙/应用程序。rb: 75:在"运行"F:/web-shared Ruby192/lib/ruby/珠宝/1.9.1/珠宝/rake-10.2.2/bin/rake: 33:在"F:/web-shared Ruby192/bin/rake: 19:"负载"F:/web-shared Ruby192/bin/rake: 19:在"Tasks: TOP => jobs:work之前

是否有人成功使用log4r处理延迟的作业?我可以使用一些指针;通过谷歌或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: '%pt%dt%X{:remote_ip}t%X{:user}t%X{:controller}t%X{:action}t%lt%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: '%pt%dt%X{:remote_ip}t%X{:user}t%X{:controller}t%X{:action}t%lt%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: '%pt%dt%X{:remote_ip}t%X{:user}t%X{:controller}t%X{:action}t%lt%m'
      type: PatternFormatter
  - type: StdoutOutputter
    name: console_production
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%pt%dt%lt%m'
      type: PatternFormatter
  - type: StdoutOutputter
    name: console_development
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%pt%dt%X{:remote_ip}t%X{:user}t%X{:controller}t%X{:action}t%lt%m'
      type: PatternFormatter
  - type: StdoutOutputter
    name: console_test
    formatter:
      date_pattern: '%H:%M:%S.%L'
      pattern: '%pt%dt%X{:remote_ip}t%X{:user}t%X{:controller}t%X{:action}t%lt%m'
      type: PatternFormatter

通过调试器运行rake任务后,我知道发生了什么。

Delayed::Worker (delayed_job/lib/delayed/worker。(代码行248)正在通过日志记录器的add方法记录一条消息,如下所示:

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

这对于Ruby的Logger类是有效和正确的,参见Logger.html#method-i-add。但是,通过使用log4r,它解析为Log4r::Logger.add (log4r/lib/log4r/logger)。(Rb第119行),它试图添加一个输出器。

我不知道为什么会发生这种情况,也不知道解决办法是什么。

你现在可以更新到delayed_jobs 4.0.1 gem,这将解决这个问题!

(有关此问题的原始评论,请参阅blog.mmlac.com)

问题是DelayedJob期望日志记录器为Rails:: logger,并调用log4r不支持的日志记录器。

在本文中,记录器变量被覆盖以使用Log4r:: logger,它不支持预期的.add调用。与Java不同,没有包来决定使用哪个记录器类,也没有slf4j将不同的记录器统一到一个标准接口。

这个问题没有简单的解决办法。一方面,您可以覆盖delayedJob的受影响部分。另一方面,您可以在delayedJob运行rails时防止加载log4r,即通过使用自定义环境:
  • 生产
  • delayedJob

这也不能保证在任何地方都能工作(任何检查rails的env == "生产"的东西都会有问题)。

另一种方法是使用环境变量并在application.rb:

中检查它们。
if (ENV["log4rlogger"] == "true") config.logger = Log4r::Logger["rails"]

相关内容

  • 没有找到相关文章

最新更新