Amazon Athena を使用して Application Load Balancer のアクセスログを分析するにはどうすればよいですか?

最終更新日: 2021 年 5 月 24 日

Amazon Athena を使用して Application Load Balancer のアクセスログを分析したいと考えています。

簡単な説明

Elastic Load Balancing のアクセスログは、デフォルトではアクティブ化されていません。アクセスログをアクティブ化する場合は、Amazon Simple Storage Service (Amazon S3) バケットを指定してください。Application Load Balancer および Classic Load Balancer のアクセスログはすべて、その S3 バケットに保存されます。ロードバランサーのパフォーマンスのトラブルシューティングまたは分析を行う際は、Athena を使用して S3 のアクセスログを分析できます。

注: Application Load Balancer でも、Classic Load Balancer でも、Athena を使用してアクセスログを分析できますが、この記事では Application Load Balancer についてのみ説明します。

解決方法

Application Load Balancer のログ用のデータベースとテーブルを作成する

Athena でアクセスログを分析するには、次を実行してデータベースとテーブルを作成します。

1.    Athena コンソールを開きます。

2.    クエリエディタで、次のようなコマンドを実行してデータベースを作成します。注意: S3 バケットと同じ AWS リージョンでデータベースを作成するのがベストプラクティスです。

create database alb_db

3.    前のステップで作成したデータベースで、Application Load Balancer のログ用のテーブル alb_log を作成します。詳細については、Application Load Balancer ログのテーブルの作成を参照してください。

注: クエリのパフォーマンスを向上させるために、パーティションプロジェクションを使用してテーブルを作成できます。パーティションプロジェクションでは、パーティションの値と場所は、AWS Glue Data Catalog などのリポジトリから読み取られるのではなく、設定から計算されます。詳細については、Amazon Athena でのパーティションプロジェクションを参照してください。

CREATE EXTERNAL TABLE IF NOT EXISTS alb_log_partition_projection (
 type string,
 time string,
 elb string,
 client_ip string,
 target_ip string,
 target_port int,
 request_processing_time double,
 target_processing_time double,
 response_processing_time double,
 elb_status_code string,
 received_bytes bigint,
 sent_bytes bigint,
 request_verb string,
 request_url string,
 request_proto string,
 user_agent string,
 ssl_cipher string,
 ssl_protocol string,
 target_group_arn string,
 trace_id string,
 domain_name string,
 chosen_cert_arn string,
 matched_rule_priority string,
 request_creation_time string,
 actions_executed string,
 redirect_url string,
 error_reason string
)
PARTITIONED BY(year int, month int, day int)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1',
'input.regex' ='([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \"([^ ]*) ([^ ]*) (- |[^ ]*)\" \"([^\"]*)\" ([A-Z0-9-]+) ([A-Za-z0-9.-]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([-.0-9]*) ([^ ]*) \"([^\"]*)\" \"([^ ]*)\" \"([^ ]*)\"' )
LOCATION 's3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/'
TBLPROPERTIES (
 'has_encrypted_data'='false',
 'projection.day.digits'='2',
 'projection.day.range'='01,31',
 'projection.day.type'='integer',
 'projection.enabled'='true',
 'projection.month.digits'='2',
 'projection.month.range'='01,12',
 'projection.month.type'='integer',
 'projection.year.digits'='4',
 'projection.year.range'='2020,2021',
 'projection.year.type'='integer',
 "storage.location.template" = "s3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/${year}/${month}/${day}"
)

ユースケースに応じて、テーブル名と S3 の場所を必ず置き換えてください。

AWS Glue クローラまたは ALTER TABLE ADD PARTITION コマンドを使用して、パーティションを含むテーブルを作成し、テーブルにロードできます。

CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs_partitioned (
 type string,
 time string,
 elb string,
 client_ip string,
 client_port int,
 target_ip string,
 target_port int,
 request_processing_time double,
 target_processing_time double,
 response_processing_time double,
 elb_status_code string,
 target_status_code string,
 received_bytes bigint,
 sent_bytes bigint,
 request_verb string,
 request_url string,
 request_proto string,
 user_agent string,
 ssl_cipher string,
 ssl_protocol string,
 target_group_arn string,
 trace_id string,
 domain_name string,
 chosen_cert_arn string,
 matched_rule_priority string,
 request_creation_time string,
 actions_executed string,
 redirect_url string,
 error_reason string
 )
 PARTITIONED BY (year string, month string, day string)
 ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
 WITH SERDEPROPERTIES (
 'serialization.format' = '1',
 'input.regex' =
 '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \"([^ ]*) ([^ ]*) (- |[^ ]*)\" \"([^\"]*)\" ([A-Z0-9-]+) ([A-Za-z0-9.-]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([-.0-9]*) ([^ ]*) \"([^\"]*)\" \"([^ ]*)\" \"([^ ]*)\"' )
 LOCATION 's3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/';
ALTER TABLE alb_logs_partitioned ADD
  PARTITION (year = '2020', month ='05', day= '21')
  LOCATION's3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/2020/05/21/'

4.     ナビゲーションペインの [Tables] (テーブル) で、テーブル名の横にあるメニューボタンから [Preview table] (テーブルのプレビュー) を選択します。Application Load Balancer アクセスログのデータは、[Results] (結果) ウィンドウに表示されます。

5.    クエリエディタを使用して、テーブルで SQL ステートメントを実行します。クエリの保存や、以前のクエリの表示、CSV 形式でのクエリ結果のダウンロードを行うことができます。

クエリの例

以下の例では、テーブル名、列の値、およびその他の変数をクエリに合わせて変更してください。

アクション クエリ

最初の 100 個のアクセスログエントリを新しい順に表示します。

ユースケース: 分析とトラブルシューティング

SELECT *
FROM alb_log
ORDER by time ASC
LIMIT 100;

Application Load Balancer にアクセスしたすべてのクライアント IP アドレスと、それらが Application Load Balancer にアクセスした回数を一覧表示します。

ユースケース: 分析とトラブルシューティング

SELECT distinct client_ip, count() as count from alb_log
GROUP by client_ip
ORDER by count() DESC;

リクエスト/レスポンスのペアで Application Load Balancer を通過しているデータの平均量 (キロバイト単位) を一覧表示します。

ユースケース: 分析とトラブルシューティング

SELECT (avg(sent_bytes)/1000.0 + avg(received_bytes)/1000.0)
as prewarm_kilobytes from alb_log;

Application Load Balancer がトラフィックをルーティングしているすべてのターゲットと、Application Load Balancer がリクエストを各ターゲットにルーティングした回数の割合分布を一覧表示します。

ユースケース: 潜在的なターゲットトラフィックの不均衡を特定する

SELECT target_ip, (Count(target_ip)* 100.0 / (Select Count(*) From alb_log))
as backend_traffic_percentage
FROM alb_log
GROUP by target_ip
ORDER By count() DESC;

クライアントが Application Load Balancer にリクエストを送信してから、アイドルタイムアウトが経過するまでに Application Load Balancer への接続を終了した時刻を一覧表示します (HTTP 460 エラー)。

ユースケース: HTTP 460 エラーをトラブルシューティングする

SELECT * from alb_log where elb_status_code = '460';

リスナールールによってリクエストが空のターゲットグループに転送されたことで、クライアントリクエストがルーティングされなかった時間を一覧表示します (HTTP 503 エラー)。

ユースケース: HTTP 503 エラーをトラブルシューティングする

SELECT * from alb_log where elb_status_code = '503';

指定された URL を訪問した回数をクライアント別、降順に一覧表示します。

ユースケース: トラフィックパターンを分析する

SELECT client_ip, elb, request_url, count(*) as count from alb_log
GROUP by client_ip, elb, request_url
ORDER by count DESC;

Firefox ユーザーが最も頻繁にアクセスした上位 10 個の URL を一覧表示します。

ユースケース: トラフィックディストリビューションおよびパターンを分析する

SELECT request_url, user_agent, count(*) as count
FROM alb_log
WHERE user_agent LIKE '%Firefox%'
GROUP by request_url, user_agent
ORDER by count(*) DESC
LIMIT 10;

各クライアントが Application Load Balancer へのリクエストで送信したデータ量 (メガバイト単位) の降順でクライアントを一覧表示します。

ユースケース: トラフィックディストリビューションおよびパターンを分析する

SELECT client_ip, sum(received_bytes/1000000.0) as client_datareceived_megabytes
FROM alb_log
GROUP by client_ip
ORDER by client_datareceived_megabytes DESC;

目標処理時間が 5 秒を超えた場合の指定された日付範囲の時間を一覧表示します。

ユースケース: 指定されたタイムフレームのレイテンシーをトラブルシューティングする

SELECT * from alb_log
WHERE (parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z')
     BETWEEN parse_datetime('2018-08-08-00:00:00','yyyy-MM-dd-HH:mm:ss')
     AND parse_datetime('2018-08-08-02:00:00','yyyy-MM-dd-HH:mm:ss'))
AND (target_processing_time >= 5.0);

ロードバランサーが受信した HTTP GET リクエストの数を、クライアント IP アドレスでグループ化してカウントします。

ユースケース: 着信トラフィックの分散を分析する

SELECT COUNT(request_verb) AS count, request_verb, client_ip FROM alb_log_partition_projection WHERE year = '2020' AND month = '05' AND day = '21' GROUP BY request_verb, client_ip;  

この記事はお役に立ちましたか?


請求に関するサポートまたは技術サポートが必要ですか?