[初心者向け]Application Load Balancerのアクセスログを、Amazon Athenaで色々なクエリを実行し分析してみた

実際に、ALBのアクセスログ分析でつかうであろうクエリもたくさん紹介します。
2023.06.02

はじめに

ALBのアクセスログを分析したい場合、利用するAWSサービスとしてAthenaが挙がると思います。

Athenaをあまり使ったことがなかったので、利用する手順をまとめました。

また、ALBのアクセスログを分析する上で、使うことが多いであろうクエリもご紹介します

事前準備

  • アクセスログ用のS3とALBを作成
  • ALBのアクセスログを有効にしておく
    • 有効化がDenyとなった場合、トラブルシューティングは、以下の記事を参考になるかと思います。

Athenaのクエリの保存先を設定

AWSマネジメントコンソールからAthenaにアクセスし、[データをクエリする]から[クエリエディタを起動]をクリックします。

最初のクエリを実行する前に、AmazonS3にクエリ結果の場所を設定する必要がありますので、[設定]タブから[管理]をクリックします

クエリ結果の場所は、どこでも良いです。今回は、アクセスログを保存しているS3バケットを指定し、保存しました。

それでは、クエリを実行します。

データベースを作成

まず、データベースを作成します。名前は、alb_dbとしました。

下記のクエリを入力し、実行します。

create database alb_db

データベースにalb_dbが追加されていますね。

テーブルを作成

続いてテーブルを作成します。

クエリは、AWSのドキュメントをそのままコピペします。

テーブル名は、alb_logsです。

CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs (
            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 int,
            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,
            lambda_error_reason string,
            target_port_list string,
            target_status_code_list string,
            classification string,
            classification_reason 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]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\s]+?)\" \"([^\s]+)\" \"([^ ]*)\" \"([^ ]*)\"')
            LOCATION 's3://your-alb-logs-directory/AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION>/'

上記のクエリのうち、41行目のLOCATIONは、ALBのアクセスログを保存している実際のS3のパスに変更します。

クエリを実行すると、テーブル名alb_logsが作成されたことが確認できます。

アクセスログの各カラムの意味は、下記ドキュメントで説明されていますので一読ください

分析する

テーブルができましたので、ALBのアクセスログを分析する上で、使うことが多いであろうクエリをご紹介します

ステータスコードの分布

ステータスコードの分布を確認できます

SELECT elb_status_code, count(elb_status_code) as count
FROM alb_logs
GROUP BY elb_status_code
ORDER BY count DESC

ステータスコード400以上をすべて出力

SELECT * 
FROM alb_logs
WHERE elb_status_code >= 400

ステータスコードが200、時間の降順で3つ出力

SELECT * 
FROM alb_logs
WHERE elb_status_code = 200
ORDER BY time DESC
LIMIT 3

ALBにアクセスしたクライアントIPアドレスを、アクセスした回数順に分布

SELECT distinct client_ip, count() as count 
FROM alb_logs 
GROUP BY client_ip 
ORDER BY count() DESC

特定の時間範囲内で、降順

時間指定時の timeカラムは、UTCなので注意です!

SELECT *
FROM alb_logs
WHERE parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z') 
    BETWEEN parse_datetime('2023-06-02-07:00:00','yyyy-MM-dd-HH:mm:ss') 
    AND parse_datetime('2023-06-02-07:20:00','yyyy-MM-dd-HH:mm:ss') 
ORDER BY time DESC

レイテンシーが高いトップ5

SELECT request_url, target_processing_time
FROM alb_logs
ORDER BY target_processing_time DESC
LIMIT 5

目標のレイテンシーの〇〇秒を超えたログを抽出

0.02秒を超えたログを抽出する場合

SELECT time, request_url, target_processing_time
FROM alb_logs
WHERE target_processing_time >= 0.002
ORDER BY time DESC

その他の例

他にもALBのアクセスログを分析するクエリの例がAWSから紹介されていますので、ご参考ください

Athenaの実行コストを下げる

Athenaの課金対象は、クエリを実行し、スキャンしたデータ量によります。

スキャンするデータ量を減らすことで、コストを削減できます。

データ量を減らす方法としては、データの圧縮、パーティション化、列指向形式に変換などが挙げられます。

具体的な簡単な方法としては、テーブルを作成する際に、特定の日付に絞る方法です。

テーブルを作成する際のクエリは、紹介しましたが、41行目のLOCATIONは、以下のようになっております。

LOCATION 's3://your-alb-logs-directory/AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION>/'

これを、特定の日付に絞ることで、スキャンするデータ量を減らすことができます。

2023/06/02に絞る場合、以下のようにします。

LOCATION 's3://your-alb-logs-directory/AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION>/2023/06/02/'

注意点としましては、同じ名前のテーブル名がすでに作成されている場合、コンソール上で削除しておく必要があります。

結果をダウンロード

クエリの結果は、[結果をダウンロード]からCSV形式でダウンロードできます。