• /
  • ログイン

Rubyカスタムインストゥルメンテーション

New Relic Rubyエージェントは、多数のメトリクスを自動収集します。また、これに含まれるAPIを利用することで、ご利用のアプリケーションに関する追加メトリクスを収集できます。トランザクショントレースの詳細に大量のアプリケーションコードセグメントがある場合は、カスタムインストゥルメンテーションによってアプリケーションで何が起きているのか、その全体像が把握しやすくなります。

ヒント

あまりにも大量のメトリクスを収集すると、ご利用のアプリケーションとNew Relicのパフォーマンスに影響が及ぶ可能性があります。データ関連の問題を回避するため、カスタムインストゥルメンテーションが採用する固有のメトリクスの合計数を2000未満に維持してください。

メソッドトレーサー

カスタムインストゥルメンテーションをキャプチャーできる最も簡単な方法は、特定のメソッドへのコールをトレースすることです。以下に解説したメソッドでトレースすることで、そのメソッドの各呼び出しに対してトランザクショントレースに追加ノードが挿入されます。こうして、トランザクションの時間進行をより詳しく把握できるようになります。

メソッドトレーサーは、あらゆるクラスのメソッドに取り付け可能なソフトウェアプローブです。このプローブは、ターゲットメソッドを実行してパフォーマンスに関するカスタムインストゥルメンテーションを収集する際、エイリアスメソッドチェイニングを使用して自らを挿入します。

クラス定義におけるトレーシング

ターゲットメソッドが先に定義されている限り、メソッドトレーサーを通常のクラス定義内で使用できます:

require 'new_relic/agent/method_tracer'
class Foo
include ::NewRelic::Agent::MethodTracer
def generate_image
...
end
add_method_tracer :generate_image, 'Custom/generate_image'
end

クラスメソッドをインストゥルメントするには、クラスシングルトンにメソッドトレーサーを追加します:

require 'new_relic/agent/method_tracer'
class Foo
def self.generate_image
...
end
class << self
include ::NewRelic::Agent::MethodTracer
add_method_tracer :generate_image, 'Custom/generate_image'
end
end

add_method_tracerは、任意のメトリック名とオプションのハッシュを取ります。詳しくは、New Relic RubyDocのadd_method_tracerを参照してください。

初期化子のトレーシング

Railsの場合、初期化子を作成してインストゥルメンテーションディレクティブに「モンキーパッチ」を適用するのが一般的なインストゥルメンテーションの追加方法となります。

たとえば、MyCache#getにメソッドトレーサーを追加するには:

  1. 必ず、メソッドトレーサーを追加する前にMyCacheクラスがロードされていることを確認してください。
  2. config/initializers/rpm_instrumentation.rbという名のファイルに、以下を追加します:
require 'new_relic/agent/method_tracer'
MyCache.class_eval do
include ::NewRelic::Agent::MethodTracer
add_method_tracer :get
end

コードブロックのトレーシング

時には、単一のメソッドが複雑すぎて、総合的な時間を追跡しても十分な詳細を得られない場合があります。こうしたケースでは、コードブロックをトレーサーでラップできます。trace_execution_scopedを呼び出して、ブロックとしてトレースするコードを渡します:

extend ::NewRelic::Agent::MethodTracer
def slow_action
self.class.trace_execution_scoped(['Custom/slow_action/beginning_work']) do
# do stuff and report execution time with a custom metric name
end
# more stuff, whose time will be "blamed" to slow_action
end

詳しくは、New Relic RubyDocのadd_method_tracerを参照してください。

トランザクションの命名

ご利用アプリケーションのスループットと合計レスポンスタイムを判断するには、インストゥルメントされたトランザクションを使用します。メソッドおよびクラス名が、New Relicにレポートされたトランザクション名として使用されます。詳しくはトランザクショントレースを表示するをご覧ください。

通常は、エージェントが自動的にトランザクション名を選択します。トランザクションの実行中にトランザクション名を変更したい場合、NewRelic::Agent.set_transaction_nameとこれに対応するNewRelic::Agent.get_transaction_nameを使用してください。

重要

トランザクション名の末尾に角括弧[suffix]を使わないでください。New Relicは名前から自動的に角括弧を除去します。代わりに、必要に応じて丸括弧(suffix)、またはその他の記号を使ってください。

これは、いくつかの基準をベースにトランザクションをセグメント化する時に便利です。たとえば、Railsでトランザクション名をレスポンスフォーマットごとに変更したい場合は:

class UsersController
def index
@users = User.all
respond_to do |format|
format.html
format.json do
NewRelic::Agent.set_transaction_name('Users/index.json')
render :json => @users
end
format.xml do
NewRelic::Agent.set_transaction_name('Users/index.xml')
render :xml => @users
end
end
end
end

トランザクションの名前変更は、一部の業務基準をめぐるリクエストのセグメント化にも利用できます。たとえば、次のようなコードを使用することで、トランザクションを「大口顧客」と「小口顧客」にセグメント化できます:

class UsersController
before_filter :segment_new_relic_by_customer_size
def segment_new_relic_by_customer_size
new_relic_name = NewRelic::Agent.get_transaction_name
if current_user.big_customer?
NewRelic::Agent.set_transaction_name("#{new_relic_name} - big customer")
else
NewRelic::Agent.set_transaction_name("#{new_relic_name} - small customer")
end
end
end

トランザクションのエントリーポイントをトレーシングする

通常、エージェントはご利用のアプリケーション内のトランザクションを特定できるものの、対応するフレームワークを使用していないか、エージェントが自動的に記録していないトランザクションを記録したい場合は、メソッドをトランザクションのエントリーポイントとして定義できます:

class Controller
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
def transaction
# execute a transaction
end
add_transaction_tracer :transaction
end

Web以外のトランザクションをインストゥルメントする

メソッドレベルのトレーシングに加え、バックグラウンドタスクなどのウェブ以外のトランザクションも、ウェブトランザクションと同レベルのトランザクションおよびエラー詳細でインストゥルメントできます。詳しくはRubyのバックグラウンド処理とデーモンを監視するを参照してください。

高度なカスタムインストゥルメンテーション

エージェントによってトレーシングコードが自動的にインストゥルメントされない場合、通常は標準のメソッドトレーサーで十分です。

ただし、単一のメソッド呼び出しより複雑な処理をインストゥルメントする必要があることもあります。たとえば、メソッド内の数行のコードをインストゥルメントする場合、またはコードのある場所でトランザクションを開始し、別の場所で終了する場合などです。

エージェントバージョン6.0で導入されたTracerモジュールには、トランザクションとセグメントを作成して、現在のトランザクションと対話できる柔軟なAPIが含まれます。

コードのセクションのインストゥルメント

コードのセクションをインストゥルメントするには、コードをブロックにラップし、そのブロックをTracer.in_transactionメソッドに渡します。

require 'new_relic/agent/tracer'
def long_and_complex_process
expensive_setup
Tracer.in_transaction(partial_name: 'Complex/process',
category: :task) do
code_to_be_instrumented
end
expensive_teardown
end

エージェントは、トランザクションが存在することを確認し、その中にブロック内のコードのためのセグメントを作成します。

トランザクションまたはセグメントの開始

コード内のある場所でトランザクションを開始し、別の場所で終了する必要がある場合は(コールバックベースのイベントで必要になります)、Tracer.start_transaction_or_segmentを呼び出します。このメソッドの戻り値に対してfinishを呼び出す必要があります

require 'new_relic/agent/tracer'
class MyEventWatcher
def event_started
@transaction = Tracer.start_transaction_or_segment(
partial_name: 'MyEventWatcher/my_event',
category: :task)
end
def event_completed
@transaction.finish
end
end

詳しくは、New Relic RubyDocのTracerを参照してください。

その他のヘルプ

その他のドキュメンテーションリソースには、以下が含まれます。

問題を作成するこのページを編集する
Copyright © 2020 New Relic Inc.