10

ActiveRecord コールバックが発生するたびに自動的にログを記録する方法はありますか? レコードに複数のコールバックが配置されている場合に、特定のことが発生した理由を追跡すると役立ちます。

どのコールバックに応答してどのメッセージが呼び出されているかを示す自動化されたログ メッセージを見たいと思います。before_validation: calling update_capitalization

4

4 に答える 4

9

私はちょうどこれのためにgemを書きました。

# Gemfile
gem "rails-callback_log", group: [:development, :test]
于 2016-06-24T22:59:26.400 に答える
3

Google と後世の場合 (Rails 3 上):

module CallbackTrace
  def self.included kls
    kls.send :alias_method_chain, :_compile_filter, :trace
  end

  def _compile_filter_with_trace filter
    generated_code = _compile_filter_without_trace(filter)
    return generated_code if filter.is_a?(Array)
    method_name = generated_code.to_s.split(%r{\(|\s}).first
    _klass = @klass
    prelogger = ->{
        Rails.logger.info("START [#{filter.class}](#{generated_code})")
        Rails.logger.info("#{_klass} #{Time.now}")
        if imethod=(_klass.instance_method(method_name) rescue nil)
          begin
            Rails.logger.info(imethod.source)
          rescue MethodSource::SourceNotFoundError
            Rails.logger.info("NO SOURCE FOR #{generated_code}")
          end
        else
          Rails.logger.info("NO METHOD: #{method_name} for #{@klass}")
        end
    }
    postlogger = ->{
      Rails.logger.info("ENDED #{generated_code} #{Time.now}")
    }
    @klass.send :define_method, "prelogger_#{method_name}", &prelogger
    @klass.send :define_method, "postlogger_#{method_name}", &postlogger
    "(prelogger_#{method_name}; retval = retval = #{generated_code}; " +
        "postlogger_#{method_name}; retval)"
  end
end
ActiveSupport::Callbacks::Callback.send :include, CallbackTrace
于 2013-07-16T04:46:50.470 に答える
0

簡単な方法は、Rails のネイティブ ロガー メソッドを使用することです。

Rails アプリケーションのデバッグ

次のように使用します。

logger.debug "Person attributes hash: #{@person.attributes.inspect}"
logger.info "Processing the request..."
logger.fatal "Terminating application, raised unrecoverable error!!!"

編集:

例外が発生したときに呼び出されたものを確認するのも面白いです

logger.error("trace: #{ex.backtrace().join("\n")}")
于 2012-10-26T16:26:04.720 に答える
0

もう 1 つの方法は、すべてのモデルでコールバックを定義してログに記録することです。すべてをロードするのを避けるために、モデルだけをロードできます。簡単にするために、これは のすべてのファイルに対応するクラスをロードしようとしますapp/models/*.rb。も使用しますが、または何でもputs使用できます。Rails.logger.info一時的なデバッグの場合、これをイニシャライザに入れることができますconfig/initializers/001_log_callbacks.rb

# Log all callbacks
Dir[Rails.root.join('app/models/*.rb').to_s].each do |filename|
  name = File.basename(filename, '.rb')
  begin
    model = name.camelize.constantize
    ActiveRecord::Callbacks::CALLBACKS.each do |callback|
      if callback.to_s.start_with?('around_')
        model.class_eval "#{callback} do |*args, &prc|; puts \"#{model}(\#{id}).#{callback} start\"; prc.call(*args) if prc; puts \"#{model}(\#{id}).#{callback} end\" end"
      else
        model.class_eval "#{callback} do; puts \"#{model}(\#{id}).#{callback}\" end"
      end
    end
  rescue
  end
end
于 2014-03-07T19:30:52.863 に答える