Rubyのコードを計測
GitLab Performance Monitoringでは、メソッドとRubyコードのカスタムブロックの両方をインスツルメンテーションすることができます。 メソッドインスツルメンテーションはインスツルメンテーションの主要な形式であり、ブロックベースのインスツルメンテーションはメソッド内のコードの特定の領域をドリルダウンしたい場合にのみ使われます。
製品の使用パターンを追跡する場合は、テレメトリーを参照してください。
計装方法
メソッドのインスツルメンテーションは、Gitlab::Metrics::Instrumentation
モジュールを使って行います。 このモジュールには、コードのインスツルメンテーションに使えるいくつかのメソッドが用意されています:
-
instrument_method
単一のクラスメソッドを使用します。 -
instrument_instance_method
インスタンスメソッドを1つ生成します。 -
instrument_class_hierarchy
クラスが与えられると、このメソッドはすべてのサブクラス (クラス・メソッドとインスタンス・メソッドの両方) を再帰的にインスツルメントします。 -
instrument_methods
: モジュールのすべての公開および非公開クラスメソッドを計測します。 -
instrument_instance_methods
: モジュールのすべての公開および非公開インスタンスメソッドを計測します。
完全なGitlab::Metrics::Instrumentation
名前空間を入力する必要をなくすには、configure
クラス・メソッドを使います。 このメソッドは、Gitlab::Metrics::Instrumentation
を引数として渡しながら、与えられたブロックを返すだけです。 例を挙げましょう:
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_method(Foo, :bar)
conf.instrument_method(Foo, :baz)
end
一般的には、この方法を使う方が、様々な計装メソッドを直接呼び出すよりも好ましい。
メソッドのインスツルメンテーションは、イニシャライザーconfig/initializers/zz_metrics.rb
で追加する必要があります。
使用例
単一メソッドのインストゥルメント:
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_method(User, :find_by)
end
クラス階層全体のインストルメンテーション
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_class_hierarchy(ActiveRecord::Base)
end
すべての公開クラス・メソッドのインスツルメンテーション:
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_methods(User)
end
インスツルメンテッド・メソッドのチェック
メソッドがインスツルメンテッド化されているかどうかを確認する最も簡単な方法は、そのソースの場所を確認することです。 例えば、以下のようになります:
method = Banzai::Renderer.method(:render)
method.source_location
ソースの位置がlib/gitlab/metrics/instrumentation.rb
を指していれば、そのメソッドがインスツルメンテーションされていることがわかります。
Pryを使用している場合、$
コマンドを使用してメソッドのソースコード(ソースの場所とともに)を表示することができます。これは上記のRubyコードを実行するよりも簡単です。 上記のスニペットの場合、以下を実行します:
$ Banzai::Renderer.render
これは次のような内容を出力します:
From: /path/to/your/gitlab/lib/gitlab/metrics/instrumentation.rb @ line 148:
Owner: #<Module:0x0055f0865c6d50>
Visibility: public
Number of lines: 21
def #{name}(#{args_signature})
if trans = Gitlab::Metrics::Instrumentation.transaction
trans.measure_method(#{label.inspect}) { super }
else
super
end
end
Rubyブロックのインスツルメンテーション
Rubyコードのブロックを計測するには、Gitlab::Metrics.measure
を呼び出してブロックを渡します。 例えば、次のようにします:
Gitlab::Metrics.measure(:foo) do
...
end
ブロックは実行され、実行時間は現在実行中のトランザクションのフィールドのセットとして保存されます。 トランザクションが存在しない場合、ブロックは何も測定せずに終了します。
1つのブロックに対して3つの値が測定されます:
-
NAME_real_time
に格納されている経過時間。 -
NAME_cpu_time
に格納されているCPU経過時間。 -
NAME_call_count
に格納されているコール数。
実際のタイミングとCPUのタイミングはどちらもミリ秒単位です。
同じブロックを複数回呼び出すと、最終的な値は個々の値の合計になります。 たとえば次のコードです:
3.times do
Gitlab::Metrics.measure(:sleep) do
sleep 1
end
end
ここでsleep_real_time
の最終値は1
ではなく 3
となります。
カスタムイベントのトラッキング
GitLab パフォーマンスモニタリングはコードのインスツルメンテーションだけでなく、カスタムイベントのトラッキングもサポートしています。 これは主に、Git プッシュ数やリポジトリインポートなどのビジネスメトリクスのトラッキングに使うことを想定しています。
カスタムイベントをトラッキングするには、Gitlab::Metrics.add_event
を呼び出し、イベント名とカスタムタグ(オプション)を渡します:
Gitlab::Metrics.add_event(:user_login, email: current_user.email)
イベント名は、push_repository
やremove_branch
のような動詞にしましょう。