开发者

Getting delayed job to log

#Here is how I have delayed job set up.

Delayed::Worker.backend = :active_record
#Delayed::Worker.logger = Rails.logger
Delayed::Worker.logger = ActiveSupport::BufferedLogger.new("log/
##{Rails.env}_delayed_jobs.log", Rails.logger.level)
Delay开发者_如何学Goed::Worker.logger.auto_flushing = 1
class Delayed::Job
    def logger
        Delayed::Worker.logger
    end
end
if JobsCommon::check_job_exists("PeriodicJob").blank?
    Delayed::Job.enqueue PeriodicJob.new(), 0, 30.seconds.from_now
end
#end


#Here is my simple job.

class PeriodicJob
    def perform
        Rails.logger.info "Periodic job writing #{Time.now}"
            Delayed::Job.enqueue PeriodicJob.new(), 0,
30.seconds.from_now
    end
end

I don't see any log messages from delayed job in my rails logs or delayed job log file, the only messages I see are jobs starting/success/failure in the delayed_jobs.log file.

this is causing big problems, including detecting bugs and memory leaks in workers almost impossible! Please help!


We've gotten it to work on Rails 3/Delayed Job 2.0.3 by hacking Rails.logger itself to use a different log file (the one we want for delayed_job entries) and also setting the delayed job logger to use the exact same object:

file_handle = File.open("log/#{Rails.env}_delayed_jobs.log", (File::WRONLY | File::APPEND | File::CREAT))
# Be paranoid about syncing, part #1
file_handle.sync = true
# Be paranoid about syncing, part #2
Rails.logger.auto_flushing = true
# Hack the existing Rails.logger object to use our new file handle
Rails.logger.instance_variable_set :@log, file_handle
# Calls to Rails.logger go to the same object as Delayed::Worker.logger
Delayed::Worker.logger = Rails.logger

If the above code doesn't work, try replacing Rails.logger with RAILS_DEFAULT_LOGGER.


This may be a simple workaround but it works well enough for me:

system("echo #{your message here} >> logfile.log")

Simple but works


I have it working with the following setup in initializer:


require 'delayed/worker'

Delayed::Worker.logger = Rails.logger

module Delayed
  class Worker
    def say_with_flushing(text, level = Logger::INFO)
      if logger
        say_without_flushing(text, level)
        logger.flush
      end
    end
    alias_method_chain :say, :flushing
  end
end



i simply did this:

/config/environments/development.rb

MyApp::Application.configure do

 [...]


 [...]


 [...]

 Delayed::Worker.logger = Rails.logger

end

In every next request you do the mail will be appear on the log.

NOTE: Sometimes you have to refresh the page to the mail be logged on the log. Don't forget to restart the server ;)


DelayedJob does not seem to output if there is something wrong:

1- Non-active record classes need to be required and initialized:

How: Create a file config/initializers/load_classes_for_dj.rb Add to it the lines:

require 'lib/libtest/delayed_test.rb'
DelayedTest

Note that if you have '#{config.root}/lib/libtest' in config.autoload_paths in config/application.rb, you do not need to do the require.

Source: Rails Delayed Job & Library Class

2- Classes that implement the Singleton module won't work by calling: SingletonClass.instance.delay.sayhello

In order to fix that, do the following:

class SingletonClass
 include Singleton

 # create a class method that does the call for you
 def self.delayed_sayhello
  SingletonClass.instance.sayhello
 end

 def sayhello
  # this is how you can actually write to delayed_job.log
  # https://stackoverflow.com/questions/9507765/delayed-job-not-logging
  Delayed::Worker.logger.add(Logger::INFO, "hello there")
 end
end

In order to call the delayed class method, do the following:

SingletonClass.delay.delayed_sayhello

Yes, I am calling .delay on a class here. Since classes in Ruby are also objects, the call is valid here and allows me to access the class method "delayed_sayhello"

3- Do not pass ActiveRecord objects or some complex objects to your call but rather pass ids, look up the objects in the database in your delayed method, and then do your work:

DO NOT DO:

DelayedClass.new.delay.do_some_processing_on_album Album.first

DO THIS INSTEAD:

    DelayedClass.new.delay.do_some_processing_on_album Album.first.id

and inside DelayedClass do_some_processing_on_album , do

a = Album.find_by_id id

There was a stackoverflow post about this that I saw a while ago -- not sure which :-)

4- For completion, this is how to do mailers (do not call the deliver method):

Notifier.delay.signup(user_id)

As per 3, do not pass the user's object but rather their id, do the lookup inside the signup method.

Now once you've ensured you have followed the guidelines above, you can use:

Delayed::Worker.logger.add(Logger::INFO, "hello")

If you are still facing issues, I suggest you break down your problem:

a- Create a new class b- Make sure you have it included and initialized as per step 1 c- Add logging from step 4 and try calling MyNewClass.new.delay to see if it works

I hope this helps you guys :-)


Don't forget to change the ActiveRecord::Base.logger

Delayed::Worker.logger = Logger.new("log/delayed_job.log", 5, 104857600)
if caller.last =~ /script\/delayed_job/ or (File.basename($0) == "rake" and ARGV[0] =~ /jobs\:work/)
  ActiveRecord::Base.logger = Delayed::Worker.logger
end

More detailed answer: Have delayed_job log "puts", sql queries and jobs status

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜