分散トレース - 開発者向けガイドライン

GitLabはディストリビューション・トレース用にインストゥルメント化されています。

オープントレースによると

分散トレース(分散リクエストトレースとも呼ばれる)は、アプリケーション、特にマイクロサービスアーキテクチャを使用して構築されたアプリケーションのプロファイリングとモニタリングに使用される手法です。 分散トレースは、障害が発生する場所やパフォーマンス低下の原因を突き止めるのに役立ちます。

分散トレースは、GitLabアプリケーションのさまざまなコンポーネントを通過するリクエストのライフサイクルを理解するのに特に役立ちます。 現時点では、Workhorse、Rails、Sidekiq、Gitalyがトレース・インストゥルメンテーションをサポートしています。

ディストリビューション・トレーシングは、無効化された場合には最小限のオーバーヘッドしか追加しませんが、有効化された場合にはわずかなオーバーヘッドしか課しません。 このため、本番環境での問題、特にパフォーマンスの問題を診断するのに役立ちます。

相関IDを使用したディストリビューションリクエストの調査

GitLabアプリケーションは、リクエスト内の様々なコンポーネント間で相関IDを渡します。 相関IDは、異なるGitLabサブシステム(例えば、Rails、Workhorse)間で単一のリクエストを相関させるために使用される、単一のリクエストに固有のトークンです。 相関IDはログ出力に含まれるため、エンジニアは相関IDを使用して異なるサブシステムからのログを相関させ、システムを通してリクエストのエンドツーエンドのパスをより良く理解することができます。 リクエストがプロセス境界を通過するとき、相関IDは送信リクエストに注入されます。 これにより、相関IDの各ダウンストリームサブシステムへの伝播が可能になります。

相関IDは通常、特定のWebリクエストに応答してRailsアプリケーション内で生成されます。 ユーザが直面するシステムの中には、ユーザのリクエストに応答して相関IDを生成しないものもあります(たとえば、SSH経由のGitプッシュなど)。

相関IDを使用するための開発者ガイドライン

新しいシステムにトレースをインテグレーションする場合、開発者は相関IDについて特定の仮定をすることを避けるべきです。 以下のガイドラインはGitLabのすべてのサブシステムに適用されます:

  • 相関IDは常にオプションです。
    • トレース以外の機能が、上流システムからの相関IDの存在に依存することはありません。
  • 相関IDは常にフリーテキストです。
    • 相関IDは、コンテキスト(ユーザー名やIPアドレスなど)の受け渡しに使用してはなりません。
    • 相関IDは決して_解析_したり、他の方法(例えば分割など)で操作してはいけません。

LabKitライブラリは、Goプログラミング言語でGitLabの相関IDを扱うための標準化されたインターフェイスを提供します。 LabKitは、Go以外のGitLabサブシステムでトレースと相関IDを扱う開発者のためのリファレンス実装として使用できます。

ディストリビューショントレースの有効化

GitLabはGITLAB_TRACING 環境変数を使って分散トレースを設定します。 すべてのコンポーネント(Workhorse、Railsなど)で同じ設定が使われます。

GITLAB_TRACING が設定されていない場合、アプリケーションはインスツルメンテーショ ンを受けません。つまり、オーバーヘッドはまったくありません。

GITLAB_TRACINGを有効にするには、URLのような形式で有効な_「configuration-string」_値を設定する必要があります:

GITLAB_TRACING=opentracing://<driver>?<param_name>=<param_value>&<param_name_2>=<param_value_2>

この例では、次のような仮想値があります:

GitLab開発キットでJaegerを使う

GitLabが最初にサポートするトレース実装はJaegerで、GitLab Development KitはJaegerによるディストリビューショントレースをすぐにサポートします。

GDK環境からトレースにアクセスする最も簡単な方法は、パフォーマンスバーからアクセスすることです。 これは、ブラウザウィンドウでp b と入力すると表示されます。

Jaeger Search UI

パフォーマンス・バーを有効にしたら、パフォーマンス・バーのトレース・リンクをクリックしてJaeger UIに移動します。

Jaegerの検索UIは、現在のリクエストのCorrelation-ID 。通常、この検索は単一のトレース結果を返します。この結果をクリックすると、階層的な時間軸でトレースの詳細が表示されます。

Jaeger Search UI

GitLab Developer KitなしでJaegerを使う場合

分散トレースは、本番環境やステージング環境だけでなく、GDK以外の開発環境でも、トラブルシューティングのために有効にすることができます。 現時点では、この機能は実験的なものであり、本番環境ではサポートされていないことに注意してください。 この最初のリリースでは、開発環境でのデバッグにのみ使用することを意図しています。

イェーガー・トレーシングは3つのステップを経て有効になります:

  1. イェーガーをスタートさせてください。
  2. GITLAB_TRACING 環境変数 を設定します。
  3. GitLabアプリケーションを起動します。
  4. ブラウザでJaeger Search UIにアクセスしてください。

1. イェーガー始動

Jaegerには多くの設定オプションがありますが、トレース保存にメモリを使用する “all-in-one “モードで起動するのが非常に簡単です(したがって、非パーシステント)。 “all-in-one “モードの主な利点は、使いやすさです。

より詳細な設定オプションについては、イェーガーのドキュメントを参照してください。

Dockerの使用

もしDockerが使えるのであれば、以下のコマンドを使ってDockerからJaeger all-in-oneを実行するのが簡単です:

$ docker run \
  --rm \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411  \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

イェーガー・プロセスの使用

Dockerがなくても、オールインワンのプロセスはセットアップが簡単です。

  1. お使いのプラットフォームの最新のJaegerリリースをダウンロードしてください。
  2. アーカイブを解凍し、bin/all-in-one プロセスを実行します。

これで、デフォルトのリスニング・ポートでプロセスが開始されるはずです。

2. GITLAB_TRACING 環境変数の設定

Jaegerを起動したら、GITLAB_TRACING 変数に適切な設定文字列を設定する必要があります。

TL;DR:すべてを同じホスト上で実行する場合は、以下の値を使用してください:

export GITLAB_TRACING="opentracing://jaeger?http_endpoint=http%3A%2F%2Flocalhost%3A14268%2Fapi%2Ftraces&sampler=const&sampler_param=1"

この設定文字列は、Jaegerドライバopentracing://jaeger 、以下のオプションを使用します:

名称 説明
http_endpoint http://localhost:14268/api/traces Jaeger がトレース情報をhttp://localhost:14268/上の HTTP エンドポイントに送信するように設定します。 あるいは、upd_endpoint を使うこともできます。
sampler const Jaeger がコンスタント・サンプラーを使うように設定します(オンかオフのどちらか)。
sampler_param 1 すべての_トレースをサンプリングするようにconst サンプラーを設定します。0 を使用すると、トレースはサンプリングさ_れません

その他のパラメータ値も可能です:

名称 説明
udp_endpoint localhost:6831 これはデフォルトです。 Jaegerがコンパクトなthriftプロトコルを使って、ポート6831 のUDPリスナーにトレース情報を送信するように設定します。 このプロトコルを使うと、Jaeger Client forRubyでいくつかイシューが発生するので注意してください。
sampler probabalistic Jaeger が確率的ランダムサンプラーを使うように設定します。 サンプルのレートはsampler_param の値で設定します。
sampler_param 0.01 0.01 の比率を使用して、probabalistic サンプラーがトレースの_1%_をランダムにサンプリングするように設定します。
注意:Workhorse、Gitaly、Rails、Sidekiqを含むすべてのGitLabプロセスの環境変数には、同じGITLAB_TRACING 値を設定する必要があります。

3. GitLabアプリケーションを起動します。

GITLAB_TRACING 環境変数がすべての GitLab サービスに exporter されたら、アプリケーションを起動します。

GITLAB_TRACING が適切に設定されている場合、アプリケーションは起動時にこのログを記録します:

13:41:53 gitlab-workhorse.1      | 2019/02/12 13:41:53 Tracing enabled
...
13:41:54 gitaly.1                | 2019/02/12 13:41:54 Tracing enabled
...

GITLAB_TRACING が正しく設定されていない場合もログに記録されます:

13:43:45 gitaly.1                | 2019/02/12 13:43:45 skipping tracing configuration step: tracer: unable to load driver mytracer

デフォルトでは、GitLabはJaegerトレーサーを同梱していますが、コンパイル時に他のトレーサーを含めることができます。 この方法の詳細は、LabKitトレーシングドキュメントに記載されています。

トレースに関するログメッセージが出力されない場合、GITLAB_TRACING 環境変数が設定されていない可能性があります。

4. イェーガー検索UIを開く

デフォルトでは、イェーガーの検索UIはhttp://localhost:16686/searchで利用可能です。

ヒント:Jaeger UIに表示される前に、アプリケーションを使用してトレースを生成する必要があることを忘れないでください。