【问题标题】:Getting delayed job to log让延迟的工作记录
【发布时间】:2011-03-30 20:03:48
【问题描述】:
#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)
Delayed::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

我在我的 rails 日志或延迟作业日志文件中没有看到任何来自延迟作业的日志消息,我看到的唯一消息是 delay_jobs.log 文件中的作业开始/成功/失败。

这会导致很大的问题,包括检测工作人员的错误和内存泄漏几乎是不可能的!请帮忙!

【问题讨论】:

    标签: ruby-on-rails delayed-job


    【解决方案1】:

    我们已经让它在 Rails 3/Delayed Job 2.0.3 上工作,方法是破解 Rails.logger 本身以使用不同的日志文件(我们想要的延迟作业条目),并将延迟作业记录器设置为使用完全相同的对象:

    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
    

    如果上述代码不起作用,请尝试将Rails.logger 替换为RAILS_DEFAULT_LOGGER

    【讨论】:

    • 你把这段代码放在哪里了?当然不只是在environment.rb...?
    • 这应该是公认的答案,因为它是写入作业状态消息、所有 SQL 查询以及自定义日志(使用 logger.level,而不是 puts)的唯一解决方案专用于delayed_job 的日志文件。
    • 我和@rfunduk 在一起 - 看起来不错,但它在应用程序中的什么位置?
    【解决方案2】:

    这可能是一个简单的解决方法,但对我来说效果很好:

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

    简单但有效

    【讨论】:

    • +1 - 谢谢!显然,这对于生产代码来说并不理想,但是当您只是试图追踪错误并确保一切都被正确调用时,它很方便。
    【解决方案3】:

    我在初始化程序中使用以下设置:

    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

    【讨论】:

    • 此代码仅将 sql 查询添加到 environment.log 文件中。没有更多的作业状态日志,也没有任何内容写入delayed_job.log
    • 最近的 Rails 无论如何都不需要这个。我有以下内容,它按预期工作:Delayed::Worker.logger = ActiveSupport::BufferedLogger.new(Rails.root.join('log/worker.log'))
    • 刚刚尝试过,worker.log 只获取作业状态消息。没有 SQL 查询,没有自定义记录器消息。
    【解决方案4】:

    我只是这样做了:

    /config/environments/development.rb
    
    MyApp::Application.configure do
    
     [...]
    
    
     [...]
    
    
     [...]
    
     Delayed::Worker.logger = Rails.logger
    
    end
    

    在您提出的每个下一个请求中,邮件都会出现在日志中。

    注意:有时您必须刷新页面才能将邮件记录在日志中。不要忘记重新启动服务器;)

    【讨论】:

    • 感谢您的提示,我已将此添加到 config/environments/application.rb 并适用于所有环境
    【解决方案5】:

    DelayedJob 出现问题时好像没有输出:

    1- 需要和初始化非活动记录类:

    如何: 创建文件 config/initializers/load_classes_for_dj.rb 添加以下行:

    require 'lib/libtest/delayed_test.rb'
    DelayedTest
    

    请注意,如果您在 config/application.rb 中的 config.autoload_paths 中有 '#{config.root}/lib/libtest',则无需执行 require。

    来源: Rails Delayed Job & Library Class

    2- 实现 Singleton 模块的类不能通过调用: SingletonClass.instance.delay.sayhello

    为了解决这个问题,请执行以下操作:

    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
    

    为了调用延迟的类方法,请执行以下操作:

    SingletonClass.delay.delayed_sayhello
    

    是的,我在这里的一个类上调用 .delay。由于 Ruby 中的类也是对象,所以调用在这里有效,并允许我访问类方法“delayed_sayhello”

    3- 不要将 ActiveRecord 对象或一些复杂对象传递给您的调用,而是传递 id,在您的延迟方法中查找数据库中的对象,然后执行您的工作:

    不要这样做:

    DelayedClass.new.delay.do_some_processing_on_album Album.first
    

    改为:

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

    在 DelayedClass do_some_processing_on_album 中,做

    a = Album.find_by_id id
    

    我不久前看到了一篇关于此的 stackoverflow 帖子——不确定是哪个 :-)

    4- 为了完成,这是如何做邮件(不要调用传递方法):

    Notifier.delay.signup(user_id)
    

    按照 3,不要传递用户的对象,而是传递他们的 id,在注册方法中进行查找。

    现在,一旦您确保已遵循上述指南,您就可以使用:

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

    如果你仍然面临问题,我建议你分解你的问题:

    a- 创建一个新类 b-确保按照步骤 1 包含并初始化它 c- 从第 4 步添加日志并尝试调用 MyNewClass.new.delay 以查看它是否有效

    我希望这对你们有帮助:-)

    【讨论】:

      【解决方案6】:

      别忘了更改 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
      

      更详细的回答:Have delayed_job log "puts", sql queries and jobs status

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-23
        • 2012-06-02
        • 1970-01-01
        • 2011-05-14
        • 2011-08-06
        • 2016-11-07
        相关资源
        最近更新 更多