AWSのLBのログをAthenaとquickSightで見れるようにする

Log(hoge_www)

概要

LBのAccesslogを解析できるようにする。
アプリケーションlogは別途考える

--

s3の設定

LBアクセスログ

項目 名前
LB AccessLog出力 hoge-alb-log/hoge-www
└── hoge-alb-log
    └── hoge-www
        └── AWSLogs
            └── accountId
                └── elasticloadbalancing
                     └── ap-northeast-1
                         └── 2018
                             └── 06
                                 └── 12

Athenaの場所

項目
s3の場所 s3://aws-athena-query-results-XXXXXX-ap-northeast-1

--

loadbalancerの設定

項目
s3の場所 hoge-alb-log/hoge-www

設定の方法

--

lambdaの設定

項目
トリガー S3
呼ばれる関数 accesslog_athena_msck
関数のロールでアクセスできるリソース
タイムアウト 10秒
実行ロール S3, Athena, Glue, CloudWatch Logs
  • トリガー設定
項目
バケット
イベントタイプ オブジェクトの作成(すべて)
プレフィックス
サフィックス .log.gz
トリガーの有効化 チェック
  • 関数サンプル(python 2.7)
import boto3
import time
 
client = boto3.client('athena')

def lambda_msck():
    sql = 'MSCK REPAIR TABLE accesslogs.hoge_www;'
    print('sql=' + sql)
    client.start_query_execution(
        QueryString=sql,
        QueryExecutionContext={
            'Database': 'accesslogs'
        },
        ResultConfiguration={
            'OutputLocation': 's3://aws-athena-query-results-XXXXXX-ap-northeast-1'
        }
    )
 
def lambda_handler(event, context):
    table_name = "accesslogs.hoge_www"
    dir_path = 'hoge-www/AWSLogs/XXXXXX/elasticloadbalancing/ap-northeast-1'
    for record in event["Records"]:
        bucket = record['s3']['bucket']['name']
        key = record['s3']['object']['key']
        key_tmp = key.split('/')
        year = key_tmp[len(key_tmp)-4]
        month = key_tmp[len(key_tmp)-3]
        day = key_tmp[len(key_tmp)-2]
        path = dir_path + '/' + year + '/' + month + '/' + day + '/'
        sql = "ALTER TABLE {} ADD IF NOT EXISTS PARTITION (year=\'{}\',month=\'{}\',day=\'{}\') location \'{}\'".format \
            (table_name, year, month , day,'s3://' + bucket + '/' + path)
        print('sql=' + sql)
        client.start_query_execution(
            QueryString=sql,
            QueryExecutionContext={
                'Database': 'accesslogs'
            },
            ResultConfiguration={
                'OutputLocation': 's3://aws-athena-query-results-XXXXXX-ap-northeast-1'
            }
        )
    lambda_msck()

S3のputなどのアクション時にeventとしてのmessageの形式
参考: Event Message Structure

{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "s3": {
        "configurationId": "testConfigRule",
        "object": {
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901",
          "key": "hoge-www/AWSLogs/XXXXXX/elasticloadbalancing/ap-northeast-1/2018/06/11/test.log",
          "size": 1024
        },
        "bucket": {
          "arn": "arn:aws:s3:::mybucket",
          "name": "hoge-www",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          }
        },
        "s3SchemaVersion": "1.0"
      },
      "responseElements": {
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH",
        "x-amz-request-id": "EXAMPLE123456789"
      },
      "awsRegion": "us-east-1",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "eventSource": "aws:s3"
    }
  ]
}

--

Athenaの設定

基本的にLBからのログは、ディレクトリごとに出力される
クエリでスキャンした容量毎に課金される
BigQueryと同じく、パーティションを作ってちゃんとスキャンされる範囲を制限してクエリを実行すれば それなりに安全ということで、本家からも推奨されてます。

ということで、日毎にpartitionを作成します。

partition addのタイミングは、
elbのlog出力により新しくs3にputされたタイミングでlambdaのfunctionが実行され、
partition追加されます。
項目
Database accesslogs
table accesslogs.hoge_www
Location of Input Data Set s3://hoge-alblog/hoge-www/AWSLogs/XXXXXX/elasticloadbalancing/ap-northeast-1/
  • CREATE TABLE サンプル
CREATE EXTERNAL TABLE IF NOT EXISTS accesslogs.hoge_www (
 `type` string,
 `timestamp` string,
 `elb` string,
 `client_port` string,
 `target_port` string,
 `request_processing_time` double,
 `target_processing_time` double,
 `response_processing_time` double,
 `elb_response_code` int,
 `backend_response_code` int,
 `received_bytes` bigint,
 `sent_bytes` bigint,
 `request` string,
 `user_agent` string,
 `ssl_cipher` string,
 `ssl_protocol` string,
 `target_group_arn` string,
 `trace_id` 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-]+) ["](.*)["] ["](.*)["] ([^ ]+) ([^ ]+) ([^ ]+) (.*)$'
 ) 
LOCATION 's3://hoge-alblog/hoge-www/AWSLogs/XXXXXX/elasticloadbalancing/ap-northeast-1/';

--

quickSightの設定

quickSightでは、athenaを参照するように設定します。
項目 mail
アカウント xxxxx xxxx
アカウント xxxxx xxxx

--

Iamの設定

ロール
accesslog_athena_msck AmazonS3FullAccess, AmazonAthenaFullAccess

--

その他 tips

パーティション追加
ALTER TABLE accesslogs.hoge_www ADD PARTITION (year='2018',month='05',day='14') location 's3://hoge-alblog/hoge-www/AWSLogs/XXXXXX/elasticloadbalancing/ap-northeast-1/2018/05/14/'
パーティションロード
MSCK REPAIR TABLE accesslogs.hoge_www;
パーティション確認
show partitions accesslogs.hoge_www;