こしごぇ(B)

旧:http://d.hatena.ne.jp/koshigoeb/

New Relic がどうやってメトリクスを集めているのか気になったのでちょっと調べてみた

Passenger の場合について簡単に調査。

PhusionPassenger.on_event(:starting_worker_process) で、NewRelic::Agent.after_fork を実行している。
NewRelic::Agent.after_fork は、Thread.new してワーカースレッドを作っている。

という事で、Passenger のワーカーインスタンスが作った Thread に NewRelic サーバへのリクエストを任せているという理解で良い気がする。

以下メモ。

newrelic_rpm-3.4.1/lib/new_relic/agent/agent.rb

  • NewRelic::Agent::Agent#start
    • -> NewRelic::Agent::Agent#check_config_and_start_agent
      • -> NewRelic::Agent::Agent#start_worker_thread
        • -> Thread.new
          • -> NewRelic::Agent::Agent#deferred_work!
  • -> NewRelic::Agent::Agent#after_fork
    • -> NewRelic::Agent::Agent#start_worker_thread
      • -> Thread.new
        • -> NewRelic::Agent::Agent#deferred_work!

newrelic_rpm-3.4.1/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb

DependencyDetection.defer do
  @name = :passenger
  
  depends_on do
    defined?(PhusionPassenger)
  end

  executes do
    NewRelic::Agent.logger.debug "Installing Passenger event hooks."

    PhusionPassenger.on_event(:stopping_worker_process) do
      NewRelic::Agent.logger.debug "Passenger stopping this process, shutdown the agent."
      NewRelic::Agent.instance.shutdown
    end

    PhusionPassenger.on_event(:starting_worker_process) do |forked|
      # We want to reset the stats from the stats engine in case any carried
      # over into the spawned process.  Don't clear them in case any were
      # cached.  We do this even in conservative spawning.
      NewRelic::Agent.after_fork(:force_reconnect => true)
    end
  end
end

newrelic_rpm-3.4.1/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb

module DependencyDetection

  module_function
  @@items = []
  def defer(&block)
    item = Dependent.new
    item.instance_eval(&block)
    @@items << item
  end

  def detect!
    @@items.each do |item|
      if item.dependencies_satisfied?
        item.execute
      end
    end
  end
...

newrelic_rpm-3.4.1/lib/new_relic/control/frameworks/rails.rb

  • NewRelic::Control::Frameworks::Rails#init_config
    • -> rails_config.after_initialize
      • -> DependencyDetection.detect!

newrelic_rpm-3.4.1/lib/new_relic/control/instrumentation.rb

  • NewRelic::Agent#add_instrumentation
    • -> NewRelic::Control::Instrumentation#add_instrumentation
      • -> NewRelic::Control::Instrumentation#load_instrumentation_files
  • NewRelic::Control#init_plugin
    • -> install_instrumentation
    • -> NewRelic::Control::Instrumentation#install_instrumentation
      • -> NewRelic::Control::Instrumentation#_install_instrumentation
        • -> NewRelic::Control::Instrumentation#load_instrumentation_files