エンジニアリング

Elastic APMのRubyエージェントでRubyアプリをインストルメントする方法

RubyアプリからAPMサーバーにパフォーマンスメトリックを送信するのは、elastic-apmRubygemをインストールするのと同じくらい簡単です。ほとんどの統合がプラグアンドプレイであり、RailsとRackのサポートが組み込まれています。

ただし、データにさらに情報を追加する方法はいくつかあり、独自のカスタムインストルメンテーションをセットアップする方法もいくつかあります。

すでにインストルメントされたパーツにさらに情報を追加する

すでに収集しているデータにさらに情報を追加することに関して、 Elastic APMにはいくつかのコンセプトがあります。

たとえば、アプリが会社というコンセプトを中心に構築されているとすると、current_company.short_nameを各トランザクションおよびエラーに割り当てることができます。タグはシンプルな key-value pairsであり、Elasticsearchにインデックスされるため、フィルターおよびクエリが可能です。そのため、自由に任意の方法でメトリックを細かく調査できます。

class ApplicationController < ActionController::Base
  before_action do
    ElasticAPM.set_label :company, current_company.short_name
  end
end

これにより、特定のパフォーマンス問題または例外が一部のお客様のみに影響を与えているかどうかがきわめて簡単に分かります。

会社のOpbeansによるリクエストのみをリスト

また、よく見られるコンセプトの1つに「ユーザー」があります。Elastic APMではそれにも対応できます。

class ApplicationController < ActionController::Base
  before_action do
    ElasticAPM.set_label :company_id, current_company.id
    ElasticAPM.set_user current_user
  end
end

Elastic APMのRubyエージェントは、渡されるすべてのデータにidemail、およびusernameフィールドを含めます。もちろん、これらのフィールド名を、アプリ内で呼びたい名前に自由にカスタマイズできます

SpanHelpersモジュール

継続時間を追跡する特定のメソッドを探している場合は、SpanHelpersモジュールを使用できます。Elastic APMのRubyエージェントには、span_methodspan_class_methodの2つのメソッドがあります。

class ThingsController < ApplicationController
  include ElasticAPM::SpanHelpers

  # ...

  def do_the_work
    # ...
  end
  span_method :do_the_work

  def self.do_other_work
    # ...
  end
  span_class_method :do_other_work

  # ... alternative syntax for newer versions of Ruby

  span_method \
  def do_the_work
    # ...
  end
end

Elastic APM RubyエージェントのSpanHelpersに関するドキュメントをご確認ください。

このアプローチは、計測対象がシンプルなメソッドコールの場合に便利です。よりきめ細かな制御が必要な場合は、汎用APIがあります。

手動でトランザクションおよびスパンを作成

手動でトランザクションおよびスパンを作成できるように、このエージェントはパブリックAPIを提供します。エージェント自体がこのAPIを内部で使用して、サポートされているライブラリのほとんどをインストルメントしています。

まず必要なのが、_transaction_です。Railsアプリ、ミドルウェアを使用したRackアプリ、またはサポートされているジョブランナーの1つでのバックグラウンドジョブのリクエスト内にいる場合は、ほぼ確実に、すでにトランザクション内にいることになります。

そうでない場合は、次のようにトランザクションを作成します。

ElasticAPM.start # if it isn't started already

begin
  transaction = ElasticAPM.start_transaction 'Optional name', 'optional.type'
  # 必ずトランザクションが終了するようにしてください。
  # 確実にそのようにするために、ここでは「begin」と「ensure」で囲みます。
ensure
  ElasticAPM.end_transaction
end

別の方法として、同じもののブロックバージョンがあり、これは後で終了させます。

ElasticAPM.with_transaction do |transaction|
  # 必要に応じてトランザクションを変更できます。例:
  transaction.name = method_that_returns_the_name

  # エージェントが起動されていない場合、`transaction`は空になりますが、それでもそのブロックは評価されることに注意してください。
end

トランザクション内の_spans_が、アプリが実行する作業の各部分になります。自動インストルメントライブラリのいずれかを使用する場合は、それをトランザクションで囲むだけです。

追加のスパンが必要な場合、APIはトランザクションに一致します。

begin
  span = ElasticAPM.start_span 'Required name', 'optional.type'
ensure
  ElasticAPM.end_span
end

# またはブロック形式
ElasticAPM.with_span 'Hard work' do |span|
  # ...
end

時間がかる理由

パブリックAPIについては、APM Rubyエージェントに関するドキュメントをご覧ください。

簡単に開始、簡単に拡張

Elastic APMのRubyエージェントの初期セットアップが最小限で簡単に済むように最善の努力をしました。上記のいずれの部分も、必要がない場合は実行する必要はありません。ほとんどの場合、いずれかを実行しなくても有用な多くの情報を得ることが可能です。

ただし、アプリについて詳細に分析したい場合は、Elastic APMでもそのためのツールを提供できるため、ご活用いただければと思います。

お試しください

Rubyは問題なく機能していますか?時間がかかっているのはどこですか?ユーザーエクスペリエスを改善するために、次のスプリントで注力すべき箇所はどこですか?Elastic APMおよびそのRubyエージェントは、そのような質問のすべてやそれ以外の質問に対する回答を得るのに役立ちます。アプリをインストルメントしましょう。そのためにはElastic Stackをダウンロードしてローカルで実行するか、または、APMサーバーが含まれているElastic Cloudの無料トライアルを使用してElasticsearch Serviceにトレースを送信してください。ご質問、アイデア、ご意見、または懸念がある場合は、ディスカッションフォーラムをご利用ください。