ここでは、New Relic の分散トレースがどのように機能するかについて、技術的な詳細を説明します。
トレースのサンプリング
トレースをどのようにサンプリングするかは、お客様の設定や使用している New Relic トレーシングツールによって異なります。たとえば、サードパーティのテレメトリサービス(OpenTelemetryなど)を利用して、データが弊社に届く前にトレースのサンプリングを実施している場合があります。また、 Infinite Tracing を使用している場合は、すべてのトレースデータを弊社に送り、弊社のサンプリングに頼ることになるでしょう。
いくつかのサンプリング戦略が利用可能です。
- ヘッドベースのサンプリング(標準のディストリビューティッド(分散)トレーシング)
- テールベースのサンプリング(Infinite Tracing)
- サンプリングなし
ヘッドベースのサンプリング(標準のディストリビューティッド(分散)トレーシング)
Infinite Tracing 機能を除いて、当社のほとんどのトレースツールはヘッドベースのサンプリングアプローチを採用しています。これは、トレース内のすべてのスパンが到着する前に、個々のスパンにフィルタを適用するものです。つまり、スパンを受け入れるかどうかの判断は、フィルタリングプロセスの最初("head" )で行われます。このようなサンプリング手法を用いることで、ストレージやパフォーマンスの問題を回避しつつ、アクティビティの代表的なサンプルを取得することができます。
標準のディストリビューティッド(分散)トレーシングツールでのヘッドベースのサンプリングの実行方法の詳細を、以下に示します。
テールベースのサンプリング(Infinite Tracing)
当社のInfinite Tracing機能は、テールベースのサンプリングアプローチを使用します。「テールベースのサンプリング」では、トレース保持の決定は、トレースのすべてのスパン到着後の処理の最終時点で行われます。
Infinite Tracingでは、お使いのアプリケーションまたはサードパーティのテレメトリサービスからトレースデータを100%当社に送信でき、Infinite Tracingが最も重要なトレースデータを解明します。また、重要なトレースが保持されるようにサンプリングを設定することができます。
サンプリングなし
当社の一部のツールはサンプリングを使用しません。これらのツールのサンプリング詳細を、以下に示します。
トレースデータの構成方法
ディストリビューティッド(分散)トレースの構造を理解すると以下のようなことに役立ちます。
- トレースがUIでどのように表示されるかを理解する
- トレースデータのクエリに役立つ
ディストリビューティッド(分散)トレーシングには木のような構造があり、一つの「親」スパンを参照する「子」スパンがあります。この図ではトレースの重要なスパン関係を示しています。
この図では、ディストリビューティッド(分散)トレーシングのスパンが相互にどのように関連しているかを示しています。
この図では、以下のような重要な概念を示しています。
トレースのルート。トレースにおける最初のサービスまたはプロセスは、ルートサービスまたはプロセスと呼ばれます。
プロセスの境界。プロセスはコードの論理部分の実行を表します。プロセスの例には、バックエンドサービスまたはLambda関数が含まれます。プロセス内のスパンは、以下のどれかに分類されます。
- 開始スパン:プロセスの最初のスパン。
- 終了スパン:a)開始スパンの親である場合、または b)
http.
またはdb.
属性を有し、そのため外部呼び出しを表す場合は、終了スパンと見なされます。 - インプロセススパン:インターナルメソッド呼び出しまたは関数を表し、終了または開始スパンではないスパン。
クライアントスパン。クライアントスパンは、別のエンティティまたは外部依存関係への呼び出しを表します。現在、以下の2つのクライアントスパンタイプがあります。
- データストア。クライアントスパンに
db.
(例:db.statement
)の属性プレフィックスがある場合ば、データストアスパンに分類されます。 - 外部。クライアントスパンに
http.
(例:http.url
) の属性プレフィックスがある、または別のプロセスに子スパンがある場合は、外部スパンに分類されます。これはデータストアクエリではない外部呼び出しに対する一般的な分類です。
- データストア。クライアントスパンに
トレース持続時間。トレースの合計持続時間は、最初のスパンの開始から最後のスパンの終了までの時間の長さで決まります。
api.newrelic.com/graphiqlでNerdGraph GraphiQLエクスプローラーを使用して、スパン関係データのクエリを行えます。
トレースデータの保存法
トレースデータの保存方法を理解するとご自分のトレースデータをクエリするのに役立ちます。
トレースデータは、次のように保存します。
スパン
:スパンはディストリビューティッド(分散)トレーシングの一部であるオペレーションを表します。スパンが表すオペレーションには、ブラウザ側のインタラクション、データストアクエリ、他のサービスの呼び出し、メソッドレベルのタイミング、Lambda関数が含まれます。一例として、HTTPサービスでは、スパンはHTTPリクエストの初めに作成され、HTTPサーバーがレスポンスを返した時に完了します。スパンの属性には、トレースの関係の詳細(traceId、GUIDなど)を含め、オペレーションに関する重要な情報(持続時間、ホストデータなど)が含まれています。スパン関連のデータについては、スパン属性を参照してください。トランザクション
:トレースのエンティティがエージェントによってモニターされる場合、そのエンティティへのリクエストが、単一トランザクション
イベントを生成します。トランザクションでは他のNew Relic機能と結びついたトレースデータを利用できます。トランザクション関連データについてはトランザクション属性を参照してください。- コンテキスト連動メタデータ。トレースとそのスパン間の関係についての計算を表示するメタデータを保存します。このデータのクエリを行うには、NerdGraph GraphiQLエクスプローラー を使用します。
アプリケーション間でトレースコンテキストを渡す方法
当社はW3Cトレースコンテキスト標準をサポートしているため、ネットワークやサービス間のトランザクションのトレースを簡単にします。ディストリビューティッド(分散)トレーシングが有効な場合、New Relicエージェントは、サービスの外部送信リクエストにHTTPヘッダーを追加します。HTTPヘッダーは、海外旅行でのパスポートのように機能します。さまざまなネットワーク、プロセス、セキュリティシステムを移動する際にソフトウェアのトレースを識別し、重要な情報を伝達します。
また、ヘッダーには、トレースID、スパンID、New RelicアカウントID、サンプリング情報などのメタデータのような、後でスパンをまとめてリンクする上で役立つ情報も含まれています。ヘッダーの詳細については、下の表を参照してください。
項目 | 説明 |
---|---|
| これは、お客様のNew RelicアカウントIDです。ただし、このIDをアカウント情報に関連付けることができるのは、アカウント管理者とNew Relic管理者だけです。 |
| これは、トレースヘッダーを生成するアプリケーションのアプリケーションIDです。 |
| ディストリビューティッド(分散)トレーシングでは、トレース内の各作業セグメントは |
親の種類 | モバイル、ブラウザ、Rubyアプリなどのトレースヘッダーのソース。これは、このヘッダーがアタッチされるリクエストによってトリガーされるトランザクションの |
優先度 | サンプリング制限に達したときに、どのデータをサンプリングするかを決定するのに役立つ、ランダムに生成された優先順位の値。これは、リクエストの一部である最初のNew Relicエージェントによって設定されたフロート値であるため、トレース内のすべてのデータは同じ優先度の値を持ちます。 |
Sampled | リクエストに対してトレースデータを収集するかどうかをエージェントに指示するブール値。これはまた、収集されたすべてのスパンおよびトランザクションデータの属性としても追加されます。このサンプリングプロセスについてさらに詳しくお読みになりたい場合は、このガイドを参照してください。 |
タイムスタンプ | ペイロードが作成されたときのUnixタイムスタンプ(ミリ秒単位)。 |
| ユニークID(ランダムに生成された文字列)で、プロセス間およびプロセス内の境界をまたがる単一のリクエストを識別するのに使用されます。このIDでは、ディストリビューティッド(分散)トレース内のスパンをリンクできます。これは、スパンおよびトランザクションデータにも属性として追加されます。 |
| トランザクションイベントの一意の識別子。 |
信頼できるアカウントキー | これは、ご利用のアカウントに関連付けられている他のアカウントを識別するのに役立つキーです。したがって、トレースが交差する複数のサブアカウントがある場合、トレースに含まれるデータが信頼できるソースから送信されたものであることを確認して、どのユーザーがデータにアクセスできるかを把握できます。 |
バージョンとデータキー | これにより、メジャー/マイナーバージョンが識別されるため、エージェントが現在のバージョンから重大な変更が加えられたバージョンのトレースヘッダーを受信した場合、そのヘッダーを拒否し、拒否と理由を報告できます。 |
このヘッダー情報は、ヘッダーの書式を認識しないミドルウェアまたはエージェントなどにより進捗が停止している場合を除き、トレースの各スパンとともに渡されます(図1を参照)。
図1
ヘッダー伝搬の問題に対処するため、当社は、2つの標準化されたヘッダーを必要とするW3Cトレースコンテキスト仕様をサポートしています。当社の最新のW3C New Relicエージェントは、この2つの必要なヘッダーを送受信し、デフォルトで以前のNew Relicエージェントのヘッダーも送受信します。
- W3C(
traceparent
):トレース全体(トレースID)と呼び出しサービス(スパンID)を識別するプライマリヘッダー。 - W3C(
tracestate
):ベンダー固有の情報を伝達し、トレースされた場所を追跡する必須ヘッダー。 - New Relic(
newrelic
):以前のNew Relicエージェントとの下位互換性を維持するために引き続き送信される、元のプロプライエタリヘッダー。
3つのヘッダーを組み合わせることで、これらのタイプのエージェントでインストゥルメントされたサービス全体にトレースを伝搬できるようになります。
- W3C New Relicエージェント
- W3C以外のNew Relicエージェント
- W3Cトレースコンテキスト対応エージェント
重要
リクエストがW3Cトレースコンテキスト対応エージェントにのみタッチする場合、New Relicヘッダーをオフにすることを選択できます。newrelicヘッダーをオフにする詳細については、エージェント設定
ドキュメントを参照してください。
以下のシナリオには、さまざまな種類の適切なヘッダ伝搬が示されています。
トレースリミット
ここでは、トレースに関する制限について説明します。
リミテッドアスペクト | リミット |
---|---|
スパンのタイムスタンプ値の最大年齢 | 20 分であること。タイムスタンプは、インジェスト時の現在時刻から20分以内、または同じ |
トレースあたりの最大スパン | 50K |
1スパンあたりの最大アトリビュート数 | 200 |
APMエージェントインスタンスごとの1分あたりの最大スパン数 | GoおよびPHP:1000。他のすべてのエージェント:2000。 |
Trace API の使用に関連するルールは、 Trace API の要件と制限 を参照してください。
その他の New Relic の制限については、 Limits をご覧ください。
トレース限界値超過
スパンレートの上限を超えると、 NrIntegrationError
event が発生します。このNRQLクエリでレートリミットメッセージを取得することができます。
SELECT * FROM NrIntegrationError WHERE newRelicFeature = 'Distributed Tracing' AND category = 'RateLimit' AND rateLimitType = 'SpansPerMinute'
制限を超えたときに通知を受けるには、 NRQL のアラート を設定します。