Closed8

AWS X-Ray の概念がいまいち押さえきれてない感じがするのでまとめる

hassaku63hassaku63

現状。

わかる:

  • 複数のサービスを横断して処理されるリクエストをサービス全体でどう流れたのか見えるようになる
  • Lambda や StepFunctions など X-Ray Integration に対応してるものがあるので、それらは有効化することでいい感じになる(upstream から渡された TraceHeader が downstream にパスされるようになる)
  • Lambda など、コード中で使うなら SDK を使って自前で patching したり、subsegment を作って annortation したりするようにコード中で書いてあげる必要がある

わからない:

  • Service map でいい感じに検索したいけど自分の環境(使い方)ではまだうまいこと使えてない。特定のリクエストに関するトレースは見えるが、あるサービス単位で見た統計値を眺めたい
  • マネコンの "Traces" をどう使えばいいのか
  • Sampling って何なのか?使い手側では何を意識すればよいのか?
  • boto3 stepfunctions client の start_execution() のオプションに TraceHeader ってのがあるが、あれは一体どう使えばいいのか?

ひとまずは公式ドキュメントを流し読みしていく方針

https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html

hassaku63hassaku63

For a distributed application, X-Ray combines nodes from all services that process requests with the same trace ID into a single service graph. The first service that the request hits adds a tracing header that is propagated between the front end and services that it calls.

同じ "トレースID" を持つものは同じサービスグラフの仲間として処理される。リクエストを最初に受け付けたサービスがトレース用のヘッダを付けて後ろを呼び出す際にその値を伝搬するようになっている


Sampling について;

To ensure efficient tracing and provide a representative sample of the requests that your application serves, the X-Ray SDK applies a sampling algorithm to determine which requests get traced. By default, the X-Ray SDK records the first request each second, and five percent of any additional requests.

どうも、全部のリクエストがトレースされてるわけではないらしい。SDK としては毎秒間隔で「最初のリクエスト」と、Sampling アルゴリズムに基づく一部のリクエストをピックアップしてトレース対象となるリクエストを選んでいる模様。

トレース対象が増えすぎると料金が跳ねるので、サンプリングレートの初期値は保守的な値になっている。
これは、SDK のインタフェースを用いるか、サービス/リクエストのプロパティで設定値を変更できる

大量の Read を扱うワークロードなどではサンプリングレートを広げたり、大事にトランザクションを扱うようなものに関してはすべてをトレースするように設定したり、といった具合でこの辺の設定変更は考えると良い。

サンプリング関係の設定方法はこちら

https://docs.aws.amazon.com/xray/latest/devguide/xray-console-sampling.html

hassaku63hassaku63

Tracing Header

The sampling decision and trace ID are added to HTTP requests in tracing headers named X-Amzn-Trace-Id
サンプリングの結果(?)とトレースIDを表現する X-Amzn-Trace-Id という HTTP header がある

一例はこんな感じ。

これは Root trace と sampling decision が出てるやつ

X-Amzn-Trace-Id: Root=1-5759e988-bd862e3fe1be46a994272793;Sampled=1

親のトレースを含む場合もある。これは upstream から来たリクエストが Trace header を持っていて、さらに自身の downstream に対するリクエストを送出する際に trace header を付与した場合でこんな感じになる

X-Amzn-Trace-Id: Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1

どうやら、全体での一貫性を保証するのが Root で、「1つ上にいる upstream」を表現するのが Parent ということになるらしい。

hassaku63hassaku63

使ったことないやつ。

どうも重要な(あるいはサマリ的な)シグナルをいい感じに拾って metrics にしたい、というモチベで利用するものらしい。

Groups

フィルタの延長として使える機能らしい。イメージは SQL の group by がやるようなグループ化とだいたい近い。

グループで集約したデータが CloudWatch metrics に 1分ごとに送られるようにできるらしい。

ただし、グループの式を変更したときの挙動には注意。グループとして集計済みのものは変わらないので、結果として metric のグラフがある時点を境に違う意味を持ってしまうことがある。

なので、そういうことが嫌ならグループを作り直すのがよい

グループの設定方法についてはこちら↓

https://docs.aws.amazon.com/xray/latest/devguide/xray-console-groups.html

hassaku63hassaku63

概念はわかるけどいまいち使いこなせてないやつ

Annotations and metadata

アノテーションは key-value 形式のデータで、追加すると Filter expression で検索属性として利用できるようになる(なので Group にも使える)

メタデータも key-value 形式のデータ。ただし value の型は問わないので Object, List 型のデータも含められる。ただし、インデックスされないので Filter expression には使用できないので検索のために使うものではない。トレースの情報量をより豊かに補足できるようになる、という用途で使うのが良さそう

hassaku63hassaku63

Errors, faults, and exceptions

トレースヘッダが付与されたリクエストに関しては、

HTTP Response Code 400, 500, 429 に関してならいい感じに取ってくれるらしい

ここに書いてあることからすると、Lambda から外の API を呼び出してそのまま戻らずに invocation timeout したらこのトレースは消失すると思われる。なので、例えば python なら urllib の timeout を指定してみたりして、Invocation timeout しないようなハンドリングをしないと有効情報が取れないということになりそう

hassaku63hassaku63

最低限わかった気はするのでクローズ。
深さ (Subsegment) 方向で annotation が伝搬するような設定ができたらいいなと思うのだが、そこはまだ未解明。

このスクラップは2022/04/24にクローズされました