Amazon Web Services ブログ

Amazon CloudWatch Logs で Application Load Balancer のログを分析する

概要

Amazon CloudWatch LogsApplication Load Balancer (ALB) のログを Vended Logs としてサポートしました。これにより、ALB の健全性とパフォーマンスを追加の設定や開発なしで可視化できます。ALB の 3 種類のログ (アクセスログ、接続ログ、ヘルスチェックログ) は、いずれもフィールド名の付いた構造化 JSON として配信されます。そのため、5xx エラーの原因がロードバランサー側かアプリケーション側かを切り分ける、レイテンシー上昇の要因になっているルートを特定する、失敗しているヘルスチェックを診断する、といった対応がすぐに行えます。Amazon S3 バケットの管理、Amazon Athena のテーブル設定、独自の ETL パイプラインは一切不要です。

以下のダッシュボードは、リクエスト量とステータスコードの分布、ロードバランサーとターゲットのどちらに起因するかを切り分けたエラー傾向、ルートごとのレイテンシーパーセンタイル、ターゲットのヘルス状態、クライアント/ターゲットの上位ランキングを表示します。このダッシュボードは、本記事で提供する AWS CloudFormation テンプレートを使ってデプロイしたものです。

Figure 1: ALB Insights dashboard showing request volume, error analysis, and latency breakdown across load balancers

図 1: ロードバランサー全体のリクエスト量、エラー分析、レイテンシー内訳を表示する ALB Insights ダッシュボード

はじめに

AWS 上でエンドユーザーに公開されるワークロードの大半では、Application Load Balancer がリクエストパス上に配置されています。ALB はアプリケーションよりも先にすべてのリクエストを受け取るため、ターゲットに到達しなかったリクエストまで把握しています。サービスに問題が生じたとき、オンコールエンジニアが最初に抱く「これはロードバランサーの問題か、ネットワークか、それとも自分のアプリケーションか」という疑問に答えてくれるのが ALB のログです。

ALB は次の 3 種類のログを出力します。

  1. アクセスログ
  2. 接続ログ
  3. ヘルスチェックログ

今回のリリース以前は、これらのログは圧縮されたスペース区切りファイルとして Amazon S3 に出力されていました。そのため、S3 のライフサイクルポリシーを管理し、ALB がフィールドを追加するたびに Athena テーブルを保守し、アラート用に別のインフラを構築する必要がありました。今後は ALB のレコードが VPC フローログ、AWS WAF ログ、アプリケーションログと同じ場所に届くため、CloudWatch Logs がすでに備えている機能をそのまま活用できます。具体的には、Log Analytics、メトリクスフィルター、Contributor Insights、Live Tail、異常検出、そしてクロスアカウント・クロスリージョンの集約です。

導入手順: 有効化とデプロイ

このセクションでは、テレメトリ有効化ルール (Telemetry enablement rules) で ALB ログの配信を有効にし、提供している CloudFormation テンプレートでサンプルダッシュボードをデプロイするまでの手順を説明します。

ステップ 1: テレメトリ有効化ルールで ALB ログの取り込みを有効化する

Amazon CloudWatch のテレメトリ有効化ルールを使うと、AWS リソースのテレメトリ収集を自動的に設定できます。ルールを使えば、組織全体でテレメトリ収集の方法を統一し、監視範囲を一定に保てます。1 つのルールは、スコープ内にある既存のロードバランサーと新しく作成されるロードバランサーの両方に配信設定を適用します。そのため、一度ロギングを有効にしておけば、デプロイパイプラインが後から作成するロードバランサーも自動的にカバーされます。

ALB ログの CloudWatch への取り込みを有効化する手順は次のとおりです。

  1. 管理アカウントまたは委任管理者アカウントで CloudWatch コンソールを開きます。
  2. ナビゲーションペインで 取り込み、続いて 有効化ルール を選択します。
  3. ルールを追加 を選択します。
  4. データソースAmazon Elastic Load Balancer – アプリケーション を選択し、テレメトリを設定 をクリックします。
  5. ルール名 に分かりやすい名前 (例: ALB-Logs-Enablement) を入力します。
  6. ルールのスコープ組織組織単位アカウント のいずれかを選択します。
Figure 2: Step 1, Specify scope, with the rule name, source accounts, optional data source tags, and target Regions

図 2: ステップ 1「範囲を指定」: ルール名、ソースアカウント、オプションのデータソースタグ、対象リージョン

  1. ロググループ名のパターン保持期間出力形式を設定し、内容を確認してルールを作成します。
  2. Telemetry typeLogs を選択し、収集したいログタイプ (アクセスログ、接続ログ、ヘルスチェックログ) を選びます。
  3. (オプション) タグのキー/値のペアを追加して、ルールの対象を一部のロードバランサーに絞り込みます (例: Environment: Production)。
Figure 3: Step 2, Specify destination, with the log group name pattern, retention, encryption, and selection of the three ALB log types

図 3: ステップ 2「送信先を指定」: ロググループ名のパターン、保持期間、暗号化、3 種類の ALB ログタイプの選択

  1. 内容を確認し、Amazon Elastic Load Balancer – アプリケーション Logs を設定 をクリックします。
Figure 4: Step 3, Review and create, summarizing the rule name, source accounts, target Regions, CloudWatch Logs destination, and selected log types

図 4: ステップ 3「確認と作成」: ルール名、ソースアカウント、対象リージョン、CloudWatch Logs の送信先、選択したログタイプのサマリー

有効化ルールが有効になると、CloudWatch はルールのスコープ内にあるリソースから ALB ログの取り込みを開始します。ログは自動的に構造化 JSON 形式へ変換され、CloudWatch Logs のロググループに保存されます。3 種類のログはすべて同じロググループに届き、次のようにログストリームのプレフィックスで区別されます。

  1. アクセスログALB_Access_Logs/app/<lb-name>/<lb-id>
  2. 接続ログALB_Connection_Logs/app/<lb-name>/<lb-id>
  3. ヘルスチェックログALB_Health_Check_Logs/app/<lb-name>/<lb-id>

ステップ 2: CloudFormation テンプレートで CloudWatch ダッシュボードをデプロイする

CloudWatch ダッシュボードは、ALB のログデータを一元的に可視化する場を提供できます。サンプルダッシュボードは、CloudWatch Log Analytics のクエリ、メトリクス、Contributor Insights ルールを組み合わせて、監視対象のすべてのロードバランサーに共通する運用上のパターンを可視化します。運用チームはトラフィックの監視、エラーの調査、ターゲットのヘルス確認を 1 か所で行えるようになります。

Figure 5: ALB insights dashboard, showing request volume, 5xx error count, worst target p99 latency, status code distribution, and health check detail

図 5: リクエスト量、5xx エラー数、最も遅いターゲットの p99 レイテンシー、ステータスコード分布、ヘルスチェック詳細を示す ALB Insights ダッシュボード

すぐに始められるよう、ダッシュボードをデプロイする CloudFormation テンプレートを用意しています。

  1. CloudFormation の YAML テンプレートをダウンロードします。
  2. AWS CloudFormation コンソールを開きます。
  3. スタックの作成 > 新しいリソースを使用 (標準) を選択します。
  4. テンプレートをアップロードし、次へ を選択します。
  5. スタック名を入力し、パラメーターを設定します。
    1. DashboardName – ダッシュボードの名前 (デフォルト: ALB-Insights)
    2. DefaultTimeRange – ダッシュボードを開いたときに表示される期間 (デフォルト: -PT3H)
    3. CreateContributorInsightsRules – Contributor Insights ルールも作成する場合は Yes、ダッシュボードだけを作成する場合は No
    4. ALBLogGroupName – ALB ログを受け取るロググループ (デフォルト: /aws/elb)。Contributor Insights ルールでのみ使用されます。
    5. ResourcePrefix – ルール名に付けるプレフィックス (デフォルト: ALB)
  6. 次へ を選択し、必要に応じてスタックオプションを設定して 次へ を選択します。
  7. 設定内容を確認し、送信 を選択します。

スタックの作成が完了すると CloudWatch ダッシュボードが利用可能になり、イベントが届くにつれて ALB ログのパターンが表示されていきます。

Figure 6: CloudFormation Resources tab showing the dashboard and both Contributor Insights rules with CREATE_COMPLETE status

図 6: ダッシュボードと 2 つの Contributor Insights ルールが CREATE_COMPLETE になった CloudFormation のリソースタブ

Log Analytics による ALB ログの分析

ダッシュボードをデプロイした後は、アドホックなクエリを直接実行することもできます。CloudWatch コンソールログ > ログ分析 を開いてください。ここでは、運用でよく問われる疑問に答えるクエリを紹介します。

5xx はロードバランサー由来かアプリケーション由来か

SOURCE logGroups()
| filterIndex @data_source_name in ["aws_alb"]
| filterIndex @data_source_type in ["access"]
| filter elb_status_code >= 500
| parse elb /^app\/(?[^\/]+)/
| fields if(target_status_code = "-", "load balancer / network", "target application") as owner
| stats count(*) as errors,
        count_distinct(target_port) as targets_affected,
        earliest(time) as first_seen,
        latest(time) as last_seen
        by owner, lb, elb_status_code
| sort errors desc

遅いルートはどれか

SOURCE logGroups()
| filterIndex @data_source_name in ["aws_alb"]
| filterIndex @data_source_type in ["access"]
| filter target_processing_time >= 0
| parse request_line /^(?\S+)\s+(?\S+)/
| parse url /^[a-z]+:\/\/[^\/]*(?[^?]*)/
| parse path /^\/(?[^\/]*)\/?(?[^\/]*)/
| fields if(s2 = "", concat("/",s1), concat("/",s1,"/",s2)) as route
| stats count(*) as requests,
        avg(target_processing_time)*1000 as avg_ms,
        pct(target_processing_time,90)*1000 as p90_ms,
        pct(target_processing_time,99)*1000 as p99_ms,
        max(target_processing_time)*1000 as max_ms
        by route
| sort p99_ms desc
| limit 15

アクセスログとヘルスチェックログを組み合わせたターゲット別の信頼性

SOURCE logGroups()
| filterIndex @data_source_name in ["aws_alb"]
| filterIndex @data_source_type in ["access","health_check"]
| fields coalesce(target_port, target_addr) as target
| filter ispresent(target)
| parse elb /^app\/(?[^\/]+)/
| stats count(request_line) as requests,
        sum(elb_status_code >= 500) as errors_5xx,
        sum(elb_status_code >= 500)*100.0/count(request_line) as error_pct,
        pct(target_processing_time,99)*1000 as p99_ms,
        count(status) as probes,
        sum(status = "FAIL") as probe_failures
        by lb, target
| sort probe_failures desc, errors_5xx desc
| limit 20

ログアラームで ALB のヘルスチェック失敗を通知する

CloudWatch ログアラームを使うと、カスタムメトリクスを用意しなくても、Log Analytics のクエリから直接アラームを作成できます。クエリはスケジュールに従って実行され、集計式が算出した数値が設定したしきい値を超えるとアラームが発生します。ログアラームは Log Analytics と同じクエリ言語を使用し、カスタムメトリクスの取り込みや保存にかかる追加費用も発生しません。

例: ヘルスチェック失敗に対するアラーム

  1. CloudWatch コンソールを開き、アラーム に移動します。
  2. アラームの作成 を選択し、データソースとして ログ を選択します。
  3. Log Analytics でクエリを作成する をクリックします。
  4. 以下のクエリを実行し、アラームに進む をクリックします。
SOURCE logGroups()
| filterIndex @data_source_name in ["aws_alb"]
| filterIndex @data_source_type in ["health_check"]
| filter status = "FAIL"
| stats count(*) as probe_failures by elb
  1. 集計式SUM(probe_failures) を入力します。
  2. アラームの状態より大きい を選択し、0 を入力します。
  3. スケジュール で実行頻度 (例: rate(5 minutes)) を選択します。
  4. 開始時間オフセット300 秒に設定します (5 分間隔のスケジュールに合わせます)。
  5. アラームを実行するデータポイント1 / 1 に設定し、最初の 1 回で検知するようにします。
  6. 通知用に Amazon SNS トピックを設定します。
  7. ログアラームを作成 を選択します。

これでアラームは 5 分ごとにクエリを評価し、ヘルスチェックのプローブがひとつでも失敗するとアラーム状態になります。

(オプション) 機能の拡張

ここまでの有効化ルールと CloudFormation テンプレートだけでも、十分に使い始められます。以下では、さらに活用したいチーム向けのオプション機能を説明します。

パイプラインで取り込み時に ALB ログをエンリッチする

CloudWatch Logs パイプラインは、取り込みの時点で ALB のレコードを処理します。これにより、ログがロググループに届く前にフィールドをエンリッチしたり、変換・整形したりできます。

パイプラインを作成する

  1. CloudWatch コンソールを開き、取り込み > パイプライン に移動します。
  2. パイプラインを作成 を選択します。
  3. 一般設定 ページで次を設定します。
    • データソースを選択AWS Application Load Balancer logs を選択します。
    • ログソースタイプ でエンリッチしたいログタイプ (Access、Connection、Health Check) を選択します。
    • Service accessAuto create and use a new service role を選択し、必要な IAM ロールを CloudWatch に作成させます。
  4. 次へ を選択し、パイプラインの送信先とロググループの設定を行います。
  5. プロセッサを設定 ページで JSON を解析 プロセッサーを選択して追加し、データを変換します。以下は ALB ログで役立つプロセッサーの例です。
    1. タイプを変換 (ミューテートイベント) – elb_status_code を文字列から整数に変換します。これにより、メトリクスフィルターでの数値比較 (例: { $.elb_status_code >= 500 }) が正しく評価されるようになります。
    2. GeoIP (エンリッチ) – client_ip フィールドを基に地理情報 (国 ISO コード、都市名、ASN の組織名) をレコードに追加し、結果を新しい client_geo フィールドへ書き込みます。条件式 (client_ip != "") を指定して、client_ip フィールドが空のレコードはスキップします。外部の IP 参照サービスを保守しなくても、「トラフィックはどこから来ているのか」をクエリだけで確認できるようになります。
    3. 翻訳 (ミューテートイベント) – 静的マッピングを使って、elb_status_code の値を人が読める elb_status_meaning フィールドに変換します (例: 503 -> “no_registered_or_healthy_targets”)。実行条件 (elb_status_code != "" かつ elb_status_code != "200") を追加してエラーレスポンスのときだけ動作させれば、成功したリクエストにはこのフィールドが付かないため、ノイズを抑えられます。
Figure 7: Configure processors page with Parse JSON, Convert Type, and GeoIP processors added

図 7: JSONを解析、タイプを変換、GeoIP プロセッサーを追加したプロセッサー設定画面

  1. Test processors を選択し、保存する前にサンプルのログイベントで設定を検証します。
  2. 内容を確認してパイプラインを作成します。

ALB ログを 1 つのアカウントに集約する

複数のアカウントにまたがってワークロードを運用している場合は、CloudWatch Logs の集約 (centralization) を使って、複数のアカウントとリージョンのロググループを 1 つの送信先アカウントに統合できます。集約されたロググループには @aws.account@aws.region のフィールドが付加されるため、プラットフォームチームは 1 か所からすべての環境をまとめてクエリできます。

詳細な手順は Amazon CloudWatch Logs の一元化を使用したログ管理の簡素化 を参照してください。

Contributor Insights

Contributor Insights は、あるパターンに寄与している上位 N 件の要因を継続的にランキングします。テンプレートは次の 2 つのルールを作成します。

ルール キーフィールド ランキング対象
TopClientIPs-ConnectionLogs $.client_ip 接続数の多いクライアント IP の上位 (接続ログから)
TopTargetsByRequests-AccessLogs $.target_port リクエスト量の多いターゲットの上位 (アクセスログから)

上位クライアント IP のルールを手動で作成する手順は次のとおりです。

  1. CloudWatch コンソールを開き、ログ > Contributor Insights に移動します。
    • もし、Contributor Insights がメニューにない場合は ログ > ログ分析 を選択し、オプトアウト (Log insights) をクリックしてください。)
  2. ルールを作成 を選択します。
  3. ロググループ で ALB のロググループ (例: /aws/elb) を選択します。
  4. ルールタイプカスタムルール を選択します。
  5. ログの形式JSON を選択します。
  6. コントリビューション で次を設定します。
    1. キー$.client_ip を入力します。
  7. フィルターを追加します。
    1. 一致$.client_ip を入力します。
    2. 状態IsPresent を選択します。
    3. true を選択します。
  8. 集計カウント を選択します。
  9. 次へ を選択します。
  10. ルール名ALB-TopClientIPs-ConnectionLogs を入力します。
  11. 次へ を選択します。
  12. ルールを作成 を選択します。
Figure 8: The TopClientIPs-ConnectionLogs rule ranking the top 10 client IPs by connection count over a three-hour window

図 8: 3 時間のウィンドウで接続数上位 10 件のクライアント IP をランキングする TopClientIPs-ConnectionLogs ルール

クリーンアップ

料金の発生を止めるには、次の順序でリソースを削除します。

  1. 取り込み > 有効化ルール からテレメトリルールを削除します。
  2. パイプラインを作成した場合は、取り込み > パイプライン から削除します。
  3. CloudFormation スタックを削除します (ダッシュボードと Contributor Insights ルールが削除されます)。
  4. ALB のロググループを削除するか、保持期間を短く設定します。

まとめ

ALB のアクセスログ、接続ログ、ヘルスチェックログが構造化 JSON として CloudWatch Logs へ直接配信されるようになり、ワークロードの入口をリクエスト単位・接続単位・ターゲット単位で可視化できるようになりました。有効化ルールを 1 つ作成すれば、AWS 組織内のすべてのロードバランサーをカバーできます。Log Analytics はロードバランサーの障害とアプリケーションの障害を切り分け、ログアラームは問題が起きたときに通知し、Contributor Insights はトラフィックの大半を占めるクライアントとターゲットを上位から示します。パイプラインもパース処理も追加のインフラも必要ありません。

まずは CloudWatch コンソールを開いて 取り込み > 有効化ルール に移動し、Application Load Balancer 向けのルールを作成してみてください。詳細は Amazon CloudWatch Logs のドキュメントを参照してください。

著者について

Raviteja Sunkavalli

Raviteja Sunkavalli

Raviteja Sunkavalli は Amazon Web Services のシニアワールドワイドスペシャリストソリューションアーキテクトで、AIOps と生成 AI のオブザーバビリティを専門としています。複雑で分散したクラウド環境において、世界中のお客様がオブザーバビリティとインシデント管理のソリューションを実装できるよう支援しています。仕事以外では、クリケットをしたり、新しい料理のレシピを試したりして過ごしています。

Siva Guruvareddiar

Siva Guruvareddiar

Siva Guruvareddiar は AWS のシニアソリューションアーキテクトで、お客様が高可用性システムを設計できるよう支援することに情熱を注いでいます。マイクロサービス、コンテナ化、オブザーバビリティ、サービスメッシュ、クラウド移行といった技術を活用してプラットフォーム基盤と内部アーキテクチャをモダナイズし、クラウドネイティブへの移行を加速させる支援をしています。LinkedIn: linkedin.com/in/sguruvar

本ブログは 2026 年 8 月 25 日に公開された Analyze Application Load Balancer Logs with Amazon CloudWatch Logs の日本語訳です。翻訳はテクニカルアカウントマネージャーの日平が行いました。