如何使用 Rufus Scheduler 在 Rails 4 外部模型中包含 Logger

How to include Logger in Rails 4 external model with Rufus Scheduler

我有 RoR 4 API。我在我的应用程序中的任何地方都使用 Logger,例如 logger.debug "..." 没有问题,我不需要包含 Logger class.

但是我有一个从任务调度程序 Rufus Scheduler(例如 cron)调用的模型。我想在这里使用 Logger,但是出现错误。我猜是因为它不包括在内。

拜托,找到我的 class:

project_root = File.dirname(File.absolute_path(__FILE__))
Dir.glob(project_root + '/events/*') {|file| require file}

class Secretary

 def self.executeEvents

   logger.debug "Secretary.executeEvents-->Executing events..."

   # and so on...

和错误:

=== puma startup: 2015-07-10 11:04:34 +0200 ===
{ 70104498803280 rufus-scheduler intercepted an error:
  70104498803280   job:
  70104498803280     Rufus::Scheduler::EveryJob "60s" {}
  70104498803280   error:
  70104498803280     70104498803280
  70104498803280     NameError
  70104498803280     undefined local variable or method `logger' for Secretary:Class
  70104498803280       /Users/Rober/Projects/yanpy/dev/yanpyapi/app/models/secretary.rb:8:in `executeEvents'
  70104498803280       /Users/Rober/Projects/yanpy/dev/yanpyapi/config/initializers/task_scheduler.rb:9:in `block in <top (required)>'
  70104498803280       /Users/Rober/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:224:in `call'
  70104498803280       /Users/Rober/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:224:in `do_trigger'
  70104498803280       /Users/Rober/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:269:in `block (3 levels) in start_work_thread'
  70104498803280       /Users/Rober/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:272:in `call'
  70104498803280       /Users/Rober/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:272:in `block (2 levels) in start_work_thread'
  70104498803280       /Users/Rober/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:258:in `loop'
  70104498803280       /Users/Rober/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:258:in `block in start_work_thread'

您需要先定义您的记录器。

def self.executeEvents
   logger = Logger.new(Rails.root.join("log", "development.log"))

   logger.debug "Secretary.executeEvents-->Executing events..."

   # and so on...
end

原因是你不是 inheriting/including Rails class 中的任何一个(比如 ActiveRecord::Base)。这并不意味着你不可以访问全局项目变量

class MyKlass

   def call
     logger.info 'bla bla'
   end

   def logger
     Rails.logger
   end
end

MyKlass.new.call

更新1:

...顺便说一句,只有当 Rails 环境/应用程序环境加载到 class 上下文中(比如在 Rake 或其他东西中)时,这才会起作用。如果不是(例如,这是项目外的独立 class),则需要执行 def logger; @logger ||= Logger.new('path/to/log'); end

更新2:

更好的方法是将其粘贴到一个模块中,并在类似的 class 未显式继承 Rails 记录器方法

的系统中将其作为通用接口重用
module RailsLoggerInterface
  def logger
    Rails.logger
  end
end

class MyKlass
  include RailsLoggerInterface

  def call
    logger.info 'bla bla'
  end
end

class OtherKlass
  include RailsLoggerInterface

  def initialize(*args)
    logger.debug("You've initialized with #{args}")
    # ...
  end

  # ...
end

更新 3

现在我意识到你在 class 方法的上下文中需要这个,所以如果你使用模块解决方案(更新 2 中提到)你可以

class Secretary
  extend RailsLoggerInterface

  def self.executeEvents

   logger.debug "Secretary.executeEvents-->Executing events..."
  end
end