概要
AthenaでALBのアクセスログの分析が非常に簡単にできるので、設定方法とよく使うクエリを紹介します。
手順
ALBアクセスログをS3に保存
新規バケットを同時に作成する場合
バケットポリシーが自動で設定されるので楽なやり方です。
ELBの属性の編集でチェックボックスをONにします。
このときにS3バケットの作成を一緒にやります。
既存のS3を使いたい場合
既存のS3バケットを保存先にしたい場合は以下のバケットポリシーを付与します。
{ "Version": "2012-10-17", "Id": "AWSConsole-AccessLogs-Policy-1549661075379", "Statement": [ { "Sid": "AWSConsoleStmt-1549661075379", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::582318560864:root" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<バケット名>/AWSLogs/<アカウントID>/*" }, { "Sid": "AWSLogDeliveryWrite", "Effect": "Allow", "Principal": { "Service": "delivery.logs.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<バケット名>/AWSLogs/<アカウントID>/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } }, { "Sid": "AWSLogDeliveryAclCheck", "Effect": "Allow", "Principal": { "Service": "delivery.logs.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::<バケット名>" } ] }
この582318560864
というのは東京リージョンのELBのアカウントIDです。
Application Load Balancer のアクセスログ - Elastic Load Balancing
delivery.logs.amazonaws.com
にAssume Roleしてますが、こちらはフローログのための権限のようです。
AthenaにALBログのテーブルの作成
項目 | 設定値 |
---|---|
テーブル名 | test_alb_logs |
LOCATION | s3://<バケット名>/AWSLogs/<アカウントID>/elasticloadbalancing/<リージョン>/ |
として以下のクエリを実行します。
LOCATION
は
- s3://<バケット名>/AWSLogs/<アカウントID>/elasticloadbalancing/<リージョン>/yyyy/
- s3://<バケット名>/AWSLogs/<アカウントID>/elasticloadbalancing/<リージョン>/yyyy/MM/
まで指定可能です。ただしdd/
までやるとテーブルでデータが見れませんでした。
Athenaの料金はスキャンするデータ量によって増えるので、このように分割して保存していくのも1つの手です。
また、どれも最後の/
を忘れずに付けてください。
CREATE EXTERNAL TABLE IF NOT EXISTS test_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 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, lambda_error_reason string, new_field 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://<バケット名>/AWSLogs/<アカウントID>/elasticloadbalancing/<リージョン>/';
Application Load Balancer ログのクエリ - Amazon Athena
注意としてELBの種類(CLB, ALB, NLB)によってフィールドの数や種類が異なります。
チュートリアルで使われるクエリもALBのものではありません。
なのでこのブログ含め、誰かのブログでなく必ず公式ドキュメントを参照してください。
動作確認
テーブル作成ができたらちゃんとデータが見れるか確認します。
Preview Logsで
このようになればOKです。
よく使うクエリ
各ステータスコードの分布を確認
SELECT elb_status_code, count(elb_status_code) as cnt FROM test_alb_logs GROUP BY elb_status_code ORDER BY cnt DESC
特定のインスタンスへのリクエストを調査
IPが10.5.20.10
というインスタンスがバックエンドにあるとして、そこへのリクエストがどうなっているか確認したいとき。
SELECT * FROM test_alb_logs WHERE target_ip = '10.5.20.10'
時間指定して調査
parse_datetime
を使ってtime
フィールドの時間帯を指定します。
以下では特定の時間帯のクライアント毎のリクエスト数を出しています。
SELECT client_ip, count(client_ip) as cnt FROM test_alb_logs WHERE parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z') BETWEEN parse_datetime('2019-01-12-12:00:00','yyyy-MM-dd-HH:mm:ss') AND parse_datetime('2019-01-13-00:00:00','yyyy-MM-dd-HH:mm:ss') GROUP BY client_ip;
latencyの高いリクエストの抽出
SELECT request_url, target_processing_time FROM test_alb_logs ORDER BY target_processing_time DESC LIMIT 10;
まとめ
以前は大変だったELBのログ調査ですが、Athenaが出てきたことで簡単に分析することができるようになりました。