

# Application Load Balancer ログをクエリする
<a name="application-load-balancer-logs"></a>

Application Load Balancer は、Elastic Load Balancing の負荷分散オプションであり、コンテナを使用したマイクロサービスのデプロイメントでのトラフィックの分散を可能にします。Application Load Balancer のログをクエリすることで、トラフィックの送信元、レイテンシー、Elastic Load Balancing インスタンスとバックエンドアプリケーションとの間で転送されるバイト数を確認できます。詳細については、「*Application Load Balancer ユーザーガイド*」の「[Access logs for your Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html)」と「[Connection logs for your Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-connection-logs.html)」を参照してください。

## 前提条件
<a name="application-load-balancer-logs-prerequisites"></a>
+ [アクセスログ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html)または[接続ログ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-connection-logs.html) を有効にして、Application Load Balancer ログを Amazon S3 バケットに保存できるようにします。
+ Athena 用に作成するテーブルを保存するデータベース。データベースを作成するには、Athena または AWS Glue コンソールを使用します。詳細については、本ガイドの「[Athena でデータベースを作成する](creating-databases.md)」または「*AWS Glue デベロッパーガイド*」の「[AWS Glue コンソールでのデータベースの操作](https://docs.aws.amazon.com/glue/latest/dg/console-databases.html)」を参照してください。

**Topics**
+ [前提条件](#application-load-balancer-logs-prerequisites)
+ [ALB アクセスログ用のテーブルを作成する](create-alb-access-logs-table.md)
+ [パーティション射影を使用して Athena で ALB アクセスログ用テーブルを作成する](create-alb-access-logs-table-partition-projection.md)
+ [ALB アクセスログのクエリ例](query-alb-access-logs-examples.md)
+ [ALB 接続ログ用テーブルを作成する](create-alb-connection-logs-table.md)
+ [パーティション射影を使用して Athena で ALB 接続ログ用テーブルを作成する](create-alb-connection-logs-table-partition-projection.md)
+ [ALB 接続ログのクエリ例](query-alb-connection-logs-examples.md)
+ [その他のリソース](application-load-balancer-logs-additional-resources.md)

# ALB アクセスログ用のテーブルを作成する
<a name="create-alb-access-logs-table"></a>

1. 次の `CREATE TABLE` ステートメントをコピーして Athena コンソールのクエリエディタに貼り付け、必要に応じて独自のログエントリ要件に合わせて変更します。Athena コンソールを開始する方法については、「[はじめに](getting-started.md)」を参照してください。`LOCATION` 句内のパスを Amazon S3 アクセスログフォルダの場所に置き換えます。アクセスログファイルの場所に関する詳細については、「*Application Load Balancer ユーザーガイド*」の「[アクセスログファイル](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-log-file-format)」を参照してください。

   各フィールドについては、「*Application Load Balancer のユーザーガイド*」の「[アクセスログのエントリ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-log-entry-format)」を参照してください。
**注記**  
次の `CREATE TABLE` ステートメントには、最近追加された `classification` 列、`classification_reason` 列、および `conn_trace_id` 列 (「traceability ID」または「TID」) が含まれています。これらのエントリを含まないApplication Load Balancer アクセスログのテーブルを作成するには、`CREATE TABLE` ステートメントから対応する列を削除し、それに応じて正規表現を変更します。

   ```
   CREATE EXTERNAL TABLE IF NOT EXISTS alb_access_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,
               conn_trace_id 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://amzn-s3-demo-bucket/access-log-folder-path/'
   ```
**注記**  
新しい ALB ログフィールドが追加された場合に備えて、将来のログエントリを処理できるように、`input.regex` パラメータの末尾に *`?( .*)?`* パターンを必ず残しておくことをお勧めします。

1. Athena コンソールでクエリを実行します。クエリが完了すると、Athena が `alb_access_logs` テーブルを登録し、その中のデータに対してクエリを発行できるように準備します。

# パーティション射影を使用して Athena で ALB アクセスログ用テーブルを作成する
<a name="create-alb-access-logs-table-partition-projection"></a>

ALB アクセスログにはパーティションスキームを事前に指定できる既知の構造があるため、Athena のパーティション射影機能を使用することで、クエリの実行時間を短縮し、パーティション管理を自動化することが可能です。新しいデータが追加されると、パーティション射影は新しいパーティションを自動で追加します。このため、`ALTER TABLE ADD PARTITION` を使用してパーティションを手動で追加する必要がなくなります。

以下の `CREATE TABLE` ステートメント例は、単一の AWS リージョンの指定された日付から現在までの ALB アクセスログに、パーティション射影を自動的に使用します。ステートメントは、前のセクションの例に基づいていますが、`PARTITIONED BY` 句および `TBLPROPERTIES` 句を追加して、パーティション射影を有効にしています。`LOCATION` 句および `storage.location.template` 句では、プレースホルダーを ALB アクセスログの Amazon S3 バケットの場所を特定する値に置き換えます。アクセスログファイルの場所に関する詳細については、「*Application Load Balancer ユーザーガイド*」の「[アクセスログファイル](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-log-file-format)」を参照してください。`projection.day.range` では、*2022*/*01*/*01* を使用を開始する日に置き換えます。クエリが正常に実行されると、テーブルをクエリできます。パーティションをロードするのに、`ALTER TABLE ADD PARTITION` を実行する必要はありません。ログファイルの各フィールドに関する詳細については、「[アクセスログのエントリ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-log-entry-format)」を参照してください。

```
CREATE EXTERNAL TABLE IF NOT EXISTS alb_access_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,
            conn_trace_id string
            )
            PARTITIONED BY
            (
             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]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\\s]+?)\" \"([^\\s]+)\" \"([^ ]*)\" \"([^ ]*)\" ?([^ ]*)? ?( .*)?'
            )
            LOCATION 's3://amzn-s3-demo-bucket/AWSLogs/<ACCOUNT-NUMBER>/elasticloadbalancing/<REGION>/'
            TBLPROPERTIES
            (
             "projection.enabled" = "true",
             "projection.day.type" = "date",
             "projection.day.range" = "2022/01/01,NOW",
             "projection.day.format" = "yyyy/MM/dd",
             "projection.day.interval" = "1",
             "projection.day.interval.unit" = "DAYS",
             "storage.location.template" = "s3://amzn-s3-demo-bucket/AWSLogs/<ACCOUNT-NUMBER>/elasticloadbalancing/<REGION>/${day}"
            )
```

パーティション射影の詳細については、「[Amazon Athena でパーティション射影を使用する](partition-projection.md)」を参照してください。

**注記**  
新しい ALB ログフィールドが追加された場合に備えて、将来のログエントリを処理できるように、`input.regex` パラメータの末尾に *?( .\$1)?* パターンを必ず残しておくことをお勧めします。

# ALB アクセスログのクエリ例
<a name="query-alb-access-logs-examples"></a>

次のクエリでは、ロードバランサーで受信し、クライアント IP アドレス別にグループ分けした HTTP GET リクエストの数をカウントします。

```
SELECT COUNT(request_verb) AS
 count,
 request_verb,
 client_ip
FROM alb_access_logs
GROUP BY request_verb, client_ip
LIMIT 100;
```

別のクエリでは、Safari ブラウザのユーザーがアクセスした URL を表示します。

```
SELECT request_url
FROM alb_access_logs
WHERE user_agent LIKE '%Safari%'
LIMIT 10;
```

次のクエリでは、ELB ステータスコードの値が 500 以上であるレコードが表示されます。

```
SELECT * FROM alb_access_logs
WHERE elb_status_code >= 500
```

次の例は、`datetime` でログを解析する方法を示しています。

```
SELECT client_ip, sum(received_bytes) 
FROM alb_access_logs
WHERE parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z') 
     BETWEEN parse_datetime('2018-05-30-12:00:00','yyyy-MM-dd-HH:mm:ss') 
     AND parse_datetime('2018-05-31-00:00:00','yyyy-MM-dd-HH:mm:ss') 
GROUP BY client_ip;
```

次のクエリは、指定された日からのすべての ALB アクセスログに対してパーティション射影を使用するテーブルをクエリします。

```
SELECT * 
FROM alb_access_logs 
WHERE day = '2022/02/12'
```

# ALB 接続ログ用テーブルを作成する
<a name="create-alb-connection-logs-table"></a>

1. 次の `CREATE TABLE` サンプルステートメントをコピーして Athena コンソールのクエリエディタに貼り付け、必要に応じて独自のログエントリ要件に合わせて変更します。Athena コンソールを開始する方法については、「[はじめに](getting-started.md)」を参照してください。`LOCATION` 句内のパスを Amazon S3 接続ログフォルダの場所に置き換えます。接続ログファイルの場所に関する詳細については、「*Application Load Balancer ユーザーガイド*」の「[接続ログファイル](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-connection-logs.html#connection-log-file-format)」を参照してください。ログファイルの各フィールドに関する詳細については、「[接続ログエントリ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-connection-logs.html#connection-log-entry-format)」を参照してください。

   ```
   CREATE EXTERNAL TABLE IF NOT EXISTS alb_connection_logs (
            time string,
            client_ip string,
            client_port int,
            listener_port int,
            tls_protocol string,
            tls_cipher string,
            tls_handshake_latency double,
            leaf_client_cert_subject string,
            leaf_client_cert_validity string,
            leaf_client_cert_serial_number string,
            tls_verify_status string,
            conn_trace_id string
            ) 
            ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
            WITH SERDEPROPERTIES (
            'serialization.format' = '1',
            'input.regex' =
             '([^ ]*) ([^ ]*) ([0-9]*) ([0-9]*) ([A-Za-z0-9.-]*) ([^ ]*) ([-.0-9]*) \"([^\"]*)\" ([^ ]*) ([^ ]*) ([^ ]*) ?([^ ]*)?( .*)?'
            )
            LOCATION 's3://amzn-s3-demo-bucket/connection-log-folder-path/'
   ```

1. Athena コンソールでクエリを実行します。クエリが完了すると、Athena が `alb_connection_logs` テーブルを登録し、その中のデータに対してクエリを発行できるように準備します。

# パーティション射影を使用して Athena で ALB 接続ログ用テーブルを作成する
<a name="create-alb-connection-logs-table-partition-projection"></a>

ALB 接続ログにはパーティションスキームを事前に指定できる既知の構造があるため、Athena のパーティション射影機能を使用することで、クエリの実行時間を短縮し、パーティション管理を自動化することが可能です。新しいデータが追加されると、パーティション射影は新しいパーティションを自動で追加します。このため、`ALTER TABLE ADD PARTITION` を使用してパーティションを手動で追加する必要がなくなります。

以下の `CREATE TABLE` ステートメント例は、単一の AWS リージョンの指定された日付から現在までの ALB 接続ログに、パーティション射影を自動的に使用します。ステートメントは、前のセクションの例に基づいていますが、`PARTITIONED BY` 句および `TBLPROPERTIES` 句を追加して、パーティション射影を有効にしています。`LOCATION` 句および `storage.location.template` 句では、プレースホルダーを ALB 接続ログの Amazon S3 バケットの場所を特定する値に置き換えます。接続ログファイルの場所に関する詳細については、「Application Load Balancer ユーザーガイド」の「[接続ログファイル](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-connection-logs.html#connection-log-file-format)」を参照してください。`projection.day.range` では、*2023*/*01*/*01* を使用したい開始日に置き換えます。クエリが正常に実行されると、テーブルをクエリできます。パーティションをロードするのに、`ALTER TABLE ADD PARTITION` を実行する必要はありません。ログファイルの各フィールドに関する詳細については、「[接続ログエントリ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-connection-logs.html#connection-log-entry-format)」を参照してください。

```
CREATE EXTERNAL TABLE IF NOT EXISTS alb_connection_logs (
         time string,
         client_ip string,
         client_port int,
         listener_port int,
         tls_protocol string,
         tls_cipher string,
         tls_handshake_latency double,
         leaf_client_cert_subject string,
         leaf_client_cert_validity string,
         leaf_client_cert_serial_number string,
         tls_verify_status string,
         conn_trace_id string
         )
            PARTITIONED BY
            (
             day STRING
            )
            ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
            WITH SERDEPROPERTIES (
            'serialization.format' = '1',
            'input.regex' =
             '([^ ]*) ([^ ]*) ([0-9]*) ([0-9]*) ([A-Za-z0-9.-]*) ([^ ]*) ([-.0-9]*) \"([^\"]*)\" ([^ ]*) ([^ ]*) ([^ ]*) ?([^ ]*)?( .*)?'
            )
            LOCATION 's3://amzn-s3-demo-bucket/AWSLogs/<ACCOUNT-NUMBER>/elasticloadbalancing/<REGION>/'
            TBLPROPERTIES
            (
             "projection.enabled" = "true",
             "projection.day.type" = "date",
             "projection.day.range" = "2023/01/01,NOW",
             "projection.day.format" = "yyyy/MM/dd",
             "projection.day.interval" = "1",
             "projection.day.interval.unit" = "DAYS",
             "storage.location.template" = "s3://amzn-s3-demo-bucket/AWSLogs/<ACCOUNT-NUMBER>/elasticloadbalancing/<REGION>/${day}"
            )
```

パーティション射影の詳細については、「[Amazon Athena でパーティション射影を使用する](partition-projection.md)」を参照してください。

# ALB 接続ログのクエリ例
<a name="query-alb-connection-logs-examples"></a>

以下のクエリは、`tls_verify_status` の値が `'Success'` ではなかったオカレンスの数をカウントし、クライアント IP アドレスごとにグループ化します。

```
SELECT DISTINCT client_ip, count() AS count FROM alb_connection_logs
WHERE tls_verify_status != 'Success'
GROUP BY client_ip
ORDER BY count() DESC;
```

以下のクエリは、指定された時間範囲内で `tls_handshake_latency` の値が 2 秒を超えたオカレンスを検索します。

```
SELECT * FROM alb_connection_logs
WHERE 
  (
    parse_datetime(time, 'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z') 
    BETWEEN 
    parse_datetime('2024-01-01-00:00:00', 'yyyy-MM-dd-HH:mm:ss') 
    AND 
    parse_datetime('2024-03-20-00:00:00', 'yyyy-MM-dd-HH:mm:ss') 
  ) 
  AND 
    (tls_handshake_latency >= 2.0);
```

# その他のリソース
<a name="application-load-balancer-logs-additional-resources"></a>

ALB ログの使用に関する詳細については、次のリソースを参照してください。
+ 「*AWS ナレッジセンター*」の「[Amazon Athena で Application Load Balancer のアクセスログを分析する方法を教えてください](https://repost.aws/knowledge-center/athena-analyze-access-logs)」。
+ Elastic Load Balancing における HTTP ステータスコードについては、「*Application Load Balancer ユーザーガイド*」の「[Application Load Balancer のトラブルシューティング](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html)」を参照してください。
+ 「*AWS Big Data Blog*」の「[Catalog and analyze Application Load Balancer logs more efficiently with AWS Glue custom classifiers and Amazon Athena](https://aws.amazon.com/blogs/big-data/catalog-and-analyze-application-load-balancer-logs-more-efficiently-with-aws-glue-custom-classifiers-and-amazon-athena/)」。