如何将Hoptoad与DelayedJob和DaemonSpawn集成?

时间:2009-08-14 05:16:13

标签: ruby-on-rails ruby hoptoad

我很高兴使用DelayedJob成语:

foo.send_later(:bar)

这会在DelayedJob进程中调用对象foo上的方法栏。

我一直在使用DaemonSpawn在我的服务器上启动DelayedJob进程。

但是......如果foo抛出异常,Hoptoad就无法捕获它。

这是否是任何这些软件包中的错误......或者我是否需要更改某些配置...或者我是否需要在DS或DJ中插入一些将调用Hoptoad通知程序的异常处理?


回应下面的第一条评论。

class DelayedJobWorker < DaemonSpawn::Base
def start(args)
  ENV['RAILS_ENV'] ||= args.first || 'development'
  Dir.chdir RAILS_ROOT
  require File.join('config', 'environment')

  Delayed::Worker.new.start
end

4 个答案:

答案 0 :(得分:5)

尝试monkeypatching Delayed :: Worker#handle_failed_job:

# lib/delayed_job_airbrake.rb

module Delayed
  class Worker

    protected

    def handle_failed_job_with_airbrake(job, error)
      say "Delayed job failed -- logging to Airbrake"
      HoptoadNotifier.notify(error)
      handle_failed_job_without_airbrake(job, error)
    end

    alias_method_chain :handle_failed_job, :airbrake

  end
end

这对我有用。

(在使用delayed_job 2.1.4和hoptoad_notifier 2.4.11的Rails 3.0.10应用程序中)

答案 1 :(得分:3)

查看Delayed :: Job的来源......有一个代码段如下:

# This is a good hook if you need to report job processing errors in additional or different ways
def log_exception(error)
  logger.error "* [JOB] #{name} failed with #{error.class.name}: #{error.message} - #{attempts} failed attempts"
  logger.error(error)
end

我没有尝试过,但我认为你可以这样做:

class Delayed::Job
  def log_exception_with_hoptoad(error)
    log_exception_without_hoptoad(error)
    HoptoadNotifier.notify(error)
  end

  alias_method_chain :log_exception, :hoptoad
end

答案 2 :(得分:1)

Hoptoad使用Rails rescue_action_in_public挂钩方法拦截异常并记录它们。只有在Rails控制器调度请求时才会执行此方法。 因此,Hoptoad完全不知道任何异常,例如rake任务或rails script / runner。

如果您想让Hoptoad跟踪您的异常,您应该手动集成它。 它应该非常简单。以下代码片段演示了如何调用Hoptoad

def rescue_action_in_public_with_hoptoad exception
  notify_hoptoad(exception) unless ignore?(exception) || ignore_user_agent?
  rescue_action_in_public_without_hoptoad(exception)
end

只需在您的环境中加入Hoptoad库,然后调用notify_hoptoad(exception)即可。确保您的环境提供与Rails控制器相同的API,否则Hoptoad可能会抱怨。

答案 3 :(得分:0)

将它扔出去 - 你的守护进程应该需要你正在处理的rails环境。它应该看起来像:

RAILS_ENV = ARGV.first || ENV['RAILS_ENV'] || 'production'
require File.join('config', 'environment')

通过这种方式,您可以指定调用守护程序的环境。

由于它运行延迟的工作机会是守护进程已经做到了(它需要activerecord),但也许你只需要最小的activerecord来使delayed_job在没有rails的情况下开心。