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
精彩评论