トレースによる根本原因分析

Keycloakおよび接続されたシステムにおけるレイテンシとエラーの根本原因を特定するために、OpenTelemetryトレーシングでリクエストライフサイクル中の情報を記録します。

このガイドでは、OpenTelemetry (OTel) を利用してKeycloakで分散トレーシングを有効化および設定する方法について説明します。トレーシングは、各リクエストのライフサイクルの詳細な監視を可能にし、問題の迅速な特定と診断を支援し、より効率的なデバッグとメンテナンスにつながります。

これは、パフォーマンスのボトルネックに関する貴重な洞察を提供し、システム全体の効率とシステム境界を越えた最適化に役立ちます。Keycloakは、アプリケーションのトレースのスムーズな統合と公開を提供する、サポートされている Quarkus OTel拡張機能 を使用しています。

トレーシングの有効化

トレースの公開は、ビルド時のオプション tracing-enabled を使用して、次のように有効にすることができます。

bin/kc.[sh|bat] start --tracing-enabled=true

デフォルトでは、トレースエクスポーターは gRPC プロトコルとエンドポイント https://#:4317 を使用して、データをバッチで送信します。

デフォルトのサービス名は keycloak であり、tracing-service-name プロパティを介して指定されます。これは、tracing-resource-attributes プロパティで定義された service.name よりも優先されます。

tracing-resource-attributes プロパティを介して提供できるリソース属性の詳細については、Quarkus OpenTelemetry Resource ガイドを参照してください。

トレーシングは、opentelemetry 機能が 有効 (デフォルト) になっている場合にのみ有効にできます。

その他のトレーシング設定については、以下のすべての可能な構成を参照してください。

開発環境のセットアップ

キャプチャされたKeycloakトレースを確認するには、Jaeger トレーシングプラットフォームを活用した基本的なセットアップを使用できます。開発目的では、Jaeger-all-in-one を使用して、可能な限り簡単にトレースを確認できます。

Jaeger-all-in-one には、Jaegerエージェント、OTelコレクター、およびクエリサービス/UIが含まれています。トレースデータを Jaeger に直接送信できるため、個別のコレクターをインストールする必要はありません。
podman|docker run --name jaeger \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
jaegertracing/all-in-one

公開ポート

16686

Jaeger UI

4317

OpenTelemetryプロトコル gRPCレシーバー (デフォルト)

4318

OpenTelemetryプロトコル HTTPレシーバー

https://#:16686/ で Jaeger UI にアクセスして、トレーシング情報を確認できます。Jaeger UI は、任意の Keycloak トレースで次のようになります。

Jaeger UI

トレース内の情報

スパン

Keycloak は、次のアクティビティに対してスパンを作成します。

  • 受信 HTTP リクエスト

  • データベース接続の取得を含む送信データベースリクエスト

  • LDAPサーバーへの接続を含む送信 LDAP リクエスト

  • IdPブローカレッジを含む送信 HTTP リクエスト

タグ

Keycloak は、リクエストのタイプに応じてトレースにタグを追加します。すべてのタグには kc. というプレフィックスが付きます。

タグの例:

kc.clientId

クライアント ID

kc.realmName

レルム名

kc.sessionId

ユーザーセッション ID

kc.token.id

トークンに記載されている id

kc.token.issuer

トークンに記載されている issuer

kc.token.sid

トークンに記載されている sid

kc.authenticationSessionId

認証セッション ID

kc.authenticationTabId

認証タブ ID

ログ

トレースがサンプリングされている場合、リクエスト中に作成されたすべてのユーザーイベントが含まれます。これには、例えば、ユーザーイベントに見られるすべての詳細とIDを含む LOGINLOGOUT、または REFRESH_TOKEN イベントが含まれます。

LDAP 通信エラーも、スタックトレースと失敗した操作の詳細とともに、記録されたトレースのログエントリとして表示されます。

ログ内のトレース ID

トレーシングが有効になっている場合、トレース ID は、有効になっているすべてのログハンドラーのログメッセージに含まれます (ロギングの設定 を参照)。これは、ログイベントをリクエストの実行に関連付けるのに役立ち、より優れたトレーサビリティとデバッグを提供する可能性があります。同じリクエストから発信されたすべてのログ行は、ログに同じ traceId を持ちます。

ログメッセージには、sampled フラグも含まれています。これは、以下で説明するサンプリングに関連しており、スパンがサンプリングされた (コレクターに送信された) かどうかを示します。

ログレコードの形式は、次のように始まる場合があります。

2024-08-05 15:27:07,144 traceId=b636ac4c665ceb901f7fdc3fc7e80154, parentId=d59cea113d0c2549, spanId=d59cea113d0c2549, sampled=true WARN  [org.keycloak.events] ...

ログ内のトレース ID を非表示にする

特定のログハンドラーでトレース ID を非表示にするには、関連付けられた Keycloak オプション log-<handler-name>-include-trace を指定します。ここで、<handler-name> はログハンドラーの名前です。たとえば、console ログでトレース情報を無効にするには、次のようにオフにすることができます。

bin/kc.[sh|bat] start --tracing-enabled=true --log=console --log-console-include-trace=false
特定のログハンドラーのログ形式を明示的にオーバーライドすると、*-include-trace オプションは効果がなくなり、トレーシングは含まれません。

サンプリング

サンプラーは、トレースを破棄するか転送するかを決定し、コレクターに送信される収集されたトレースの数を制限することで、オーバーヘッドを効果的に削減します。これにより、リソース消費を管理し、すべての単一リクエストをトレースすることによる莫大なストレージコストと潜在的なパフォーマンスの低下を回避できます。

本番環境に対応した環境の場合、インフラストラクチャコストを最小限に抑えるために、サンプリングを適切に設定する必要があります。

Keycloak は、次のような、いくつかの組み込み OpenTelemetry サンプラーをサポートしています。

  • always_on

  • always_off

  • traceidratio (デフォルト)

  • parentbased_always_on

  • parentbased_always_off

  • parentbased_traceidratio

使用されるサンプラーは、tracing-sampler-type プロパティを介して変更できます。

デフォルトサンプラー

Keycloak のデフォルトサンプラーは traceidratio であり、tracing-sampler-ratio プロパティを介して設定可能な指定された比率に基づいてトレースサンプリングのレートを制御します。

トレース比率

デフォルトのトレース比率は 1.0 であり、これはすべてのトレースがサンプリングされ、コレクターに送信されることを意味します。比率は [0,1] の範囲の浮動小数点数です。たとえば、比率が 0.1 の場合、トレースの 10% のみがサンプリングされます。

本番環境に対応した環境の場合、トレース比率は、トレースストアインフラストラクチャの莫大なコストを防ぎ、パフォーマンスのオーバーヘッドを回避するために、より小さい数にする必要があります。
比率は 0.0 に設定して、実行時 にサンプリングを完全に無効にすることができます。

根拠

サンプラーは、parentbased_traceidratio サンプラーを使用する場合と同様に、親スパンで行われた決定に関係なく、サンプリングされたスパンの現在の比率に基づいて独自のサンプリング決定を行います。

parentbased_traceidratio サンプラーは、親スパンと子スパン間のサンプリングの一貫性を保証するため、推奨されるデフォルトタイプになる可能性があります。具体的には、親スパンがサンプリングされる場合、そのすべての子スパンもサンプリングされます。すべてに同じサンプリング決定が適用されます。これにより、すべてのスパンをまとめて保持し、不完全なトレースの保存を防ぐことができます。

ただし、DoS攻撃につながる特定のセキュリティリスクが発生する可能性があります。外部の呼び出し元は、トレースヘッダーを操作したり、親スパンを挿入したり、トレースストアが過負荷になったりする可能性があります。適切な HTTP ヘッダー (特に tracestate) のフィルタリングと、呼び出し元の信頼の適切な対策を評価する必要があります。

詳細については、W3C Trace context ドキュメントを参照してください。

Kubernetes 環境でのトレーシング

Keycloak Operator を使用してトレーシングが有効になっている場合、デプロイメントに関する特定の情報が基盤となるコンテナに伝播されます。

Keycloak CR による設定

Keycloak CR を介してトレーシング設定を変更できます。詳細については、高度な設定 を参照してください。

Kubernetes 属性に基づいてトレースをフィルタリングする

トレーシングバックエンドで、必要なトレースをタグに基づいてフィルタリングできます。

  • service.name - Keycloak デプロイメント名

  • k8s.namespace.name - 名前空間

  • host.name - Pod 名

Keycloak Operator は、管理する Pod に含まれる各 Keycloak コンテナに対して、KC_TRACING_SERVICE_NAME および KC_TRACING_RESOURCE_ATTRIBUTES 環境変数を自動的に設定します。

KC_TRACING_RESOURCE_ATTRIBUTES 変数には、(オーバーライドされていない場合) 現在の名前空間を表す k8s.namespace.name 属性が常に含まれています。

関連オプション

log-console-include-trace

コンソールログにトレーシング情報を含めます。

log-console-format オプションが指定されている場合、このオプションは効果がありません。

CLI: --log-console-include-trace
Env: KC_LOG_CONSOLE_INCLUDE_TRACE

コンソールログハンドラーとトレーシングが有効になっている場合にのみ使用可能

true (デフォルト), false

log-file-include-trace

ファイルログにトレーシング情報を含めます。

log-file-format オプションが指定されている場合、このオプションは効果がありません。

CLI: --log-file-include-trace
Env: KC_LOG_FILE_INCLUDE_TRACE

ファイルログハンドラーとトレーシングが有効になっている場合にのみ使用可能

true (デフォルト), false

log-syslog-include-trace

Syslog にトレーシング情報を含めます。

log-syslog-format オプションが指定されている場合、このオプションは効果がありません。

CLI: --log-syslog-include-trace
Env: KC_LOG_SYSLOG_INCLUDE_TRACE

Syslog ハンドラーとトレーシングが有効になっている場合にのみ使用可能

true (デフォルト), false

tracing-compression

ペイロードを圧縮するために使用される OpenTelemetry 圧縮メソッド。

設定しない場合、圧縮は無効になります。

CLI: --tracing-compression
Env: KC_TRACING_COMPRESSION

トレーシングが有効になっている場合にのみ使用可能

gzip, none (デフォルト)

tracing-enabled

OpenTelemetry トレーシングを有効にします。

CLI: --tracing-enabled
Env: KC_TRACING_ENABLED

「opentelemetry」機能が有効になっている場合にのみ使用可能

true, false (デフォルト)

tracing-endpoint

接続する OpenTelemetry エンドポイント。

CLI: --tracing-endpoint
Env: KC_TRACING_ENDPOINT

トレーシングが有効になっている場合にのみ使用可能

https://#:4317 (デフォルト)

tracing-jdbc-enabled

OpenTelemetry JDBC トレーシングを有効にします。

CLI: --tracing-jdbc-enabled
Env: KC_TRACING_JDBC_ENABLED

トレーシングが有効になっている場合にのみ使用可能

true (デフォルト), false

tracing-protocol

テレメトリデータに使用される OpenTelemetry プロトコル。

CLI: --tracing-protocol
Env: KC_TRACING_PROTOCOL

トレーシングが有効になっている場合にのみ使用可能

grpc (デフォルト), http/protobuf

tracing-resource-attributes

テレメトリプロデューサーを特徴付けるために、エクスポートされたトレースに存在する OpenTelemetry リソース属性。

形式 key1=val1,key2=val2 の値。詳細については、トレーシングガイドを確認してください。

CLI: --tracing-resource-attributes
Env: KC_TRACING_RESOURCE_ATTRIBUTES

トレーシングが有効になっている場合にのみ使用可能

tracing-sampler-ratio

OpenTelemetry サンプラー比率。

スパンがサンプリングされる確率。[0,1] の区間の double 値が予想されます。

CLI: --tracing-sampler-ratio
Env: KC_TRACING_SAMPLER_RATIO

トレーシングが有効になっている場合にのみ使用可能

1.0 (デフォルト)

tracing-sampler-type

トレーシングに使用する OpenTelemetry サンプラー。

CLI: --tracing-sampler-type
Env: KC_TRACING_SAMPLER_TYPE

トレーシングが有効になっている場合にのみ使用可能

always_on, always_off, traceidratio (デフォルト), parentbased_always_on, parentbased_always_off, parentbased_traceidratio

tracing-service-name

OpenTelemetry サービス名。

tracing-resource-attributes プロパティで定義された service.name よりも優先されます。

CLI: --tracing-service-name
Env: KC_TRACING_SERVICE_NAME

トレーシングが有効になっている場合にのみ使用可能

keycloak (デフォルト)

このページ内