Rober
Rober

Reputation: 6108

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

I have RoR 4 API. I´m using Logger wherever in my app, in example logger.debug "..." without problems and I don´t need to include the Logger class.

However I have a model that is called from a task scheduler Rufus Scheduler (such as cron). I would like to use the Logger here, however, I got an error. I guess because it´s not included.

Please, find my 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...

and the error:

=== 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'

Upvotes: 1

Views: 1708

Answers (2)

equivalent8
equivalent8

Reputation: 14227

The reason for this is that you are not inheriting/including any of the Rails classes (like ActiveRecord::Base. That doesn't mean you don't have access to the global project variables

class MyKlass

   def call
     logger.info 'bla bla'
   end

   def logger
     Rails.logger
   end
end

MyKlass.new.call

Update1:

...btw this will work only if the Rails environment / Application environment is loaded in that class context (like inside Rake or something). If not (e.g. this is a standalone class outside the project) you need to do def logger; @logger ||= Logger.new('path/to/log'); end

Update2:

Even better is to stick this to a module and reuse this as a common interface in similar classes that don't explicitly inherit Rails logger method

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

Update 3

now I realized you need this in context of class method, so if you go with the module solution (mentioned in Update 2) you can do

class Secretary
  extend RailsLoggerInterface

  def self.executeEvents

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

Upvotes: 4

Māris Cīlītis
Māris Cīlītis

Reputation: 173

You need to define your logger first.

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

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

   # and so on...
end

Upvotes: 1

Related Questions