Amazon Athena で Amazon S3 サーバーアクセスログを分析する方法を教えてください。

所要時間3分
1

Amazon Athena で、Amazon Simple Storage Service (Amazon S3) のサーバーアクセスログをクエリしようと思います。

解決策

Amazon S3 では、サーバーアクセスログがオブジェクトとしてS3 バケットに保存されます。Athena でサーバーアクセスログを分析し、S3 クエリを行うには、次の手順に従います。

  1. 有効になっていなければ、S3 バケットのサーバーアクセスログ記録を有効にします。[ターゲットバケット] と **[ターゲットプレフィックス]**の値を書き留めておきます。Athena クエリで Amazon S3 の場所を指定するには、両方が必要です。
    注: ログオブジェクトキー形式では、日付ベースのパーティション化を選択して、分析アプリケーションとクエリアプリケーションを高速化します。

  2. Amazon Athena コンソールを開きます。
    注: 最初のクエリを実行する前に、場合によっては、Amazon S3 にクエリ結果の場所を設定します

  3. [クエリエディタ] で、DDL ステートメントを実行してデータベースを作成します。
    **注:**S3 バケットと同じ AWS リージョンにデータベースを作成するのがベストプラクティスです。

    create database s3_access_logs_db
  4. データベースにテーブルスキーマを作成します。次の例では、STRINGBIGINT のデータ型の値がアクセスログのプロパティです。これらのプロパティは Athena でクエリできます。[LOCATION] に、手順 1 の S3 バケットとプレフィックスのパスを入力します。プレフィックスの末尾にはフォワードスラッシュ (/) を含めてください (例: s3://doc-example-bucket/prefix/)。プレフィックスを使用しない場合は、バケット名の末尾にフォワードスラッシュ (/) を含めてください (例: s3://doc-example-bucket/)。

    CREATE EXTERNAL TABLE s3_access_logs_db.mybucket_logs(
     `bucketowner` STRING,
     `bucket_name` STRING,
     `requestdatetime` STRING,
     `remoteip` STRING,
     `requester` STRING,
     `requestid` STRING,
     `operation` STRING,
     `key` STRING,
     `request_uri` STRING,
     `httpstatus` STRING,
     `errorcode` STRING,
     `bytessent` BIGINT,
     `objectsize` BIGINT,
     `totaltime` STRING,
     `turnaroundtime` STRING,
     `referrer` STRING,
     `useragent` STRING,
     `versionid` STRING,
     `hostid` STRING,
     `sigv` STRING,
     `ciphersuite` STRING,
     `authtype` STRING,
     `endpoint` STRING,
     `tlsversion` STRING,
     `accesspointarn` STRING,
     `aclrequired` STRING)
     PARTITIONED BY (
       `timestamp` string)
    ROW FORMAT SERDE
     'org.apache.hadoop.hive.serde2.RegexSerDe'
    WITH SERDEPROPERTIES (
     'input.regex'='([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$')
    STORED AS INPUTFORMAT
     'org.apache.hadoop.mapred.TextInputFormat'
    OUTPUTFORMAT
     'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    LOCATION
     's3://bucket-name/prefix-name/account-id/region/source-bucket-name/'
     TBLPROPERTIES (
      'projection.enabled'='true',
      'projection.timestamp.format'='yyyy/MM/dd',
      'projection.timestamp.interval'='1',
      'projection.timestamp.interval.unit'='DAYS',
      'projection.timestamp.range'='2024/01/01,NOW',
      'projection.timestamp.type'='date',
      'storage.location.template'='s3://bucket-name/prefix-name/account-id/region/source-bucket-name/${timestamp}')
  5. 左側のペインの [テーブル] で、テーブル名の横にある省略記号を選択し、[テーブルのプレビュー]を選択します。[結果] ウィンドウにサーバーアクセスログのデータが表示されていれば、Athena テーブルは正常に作成されています。データは、bucketownerbucket_namerequestdatetimeのような値です。

これで、Amazon S3 サーバーアクセスログをクエリできます。

クエリの例

削除したオブジェクトのリクエストを検索するには、次のクエリを使用します:

SELECT * FROM s3_access_logs_db.mybucket_logs WHERE key = 'images/picture.jpg' AND operation like '%DELETE%';

403 Access Denied エラーが発生したリクエストの Amazon S3 リクエスト ID を表示するには、次のクエリを使用します:

SELECT requestdatetime, requester, operation, requestid, hostid FROM s3_access_logs_db.mybucket_logs
WHERE httpstatus = '403';

特定の期間中の HTTP 5xx エラーの Amazon S3 リクエスト ID (キーとエラーコードを含む) を検索するには、次のクエリを実行します:

SELECT requestdatetime, key, httpstatus, errorcode, requestid, hostid FROM s3_access_logs_db.mybucket_logs WHERE httpstatus like '5%'
AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

タイムスタンプ、IP アドレス、AWS Identity and Access Management (IAM) ロールとともに、誰がいつオブジェクトを削除したかを表示するには、次のクエリを使用します:

SELECT requestdatetime, remoteip, requester, key FROM s3_access_logs_db.mybucket_logs
WHERE key = 'images/picture.jpg'
AND operation like '%DELETE%';

IAM ロールによって実行されたすべての操作を表示するには、次のクエリを使用します:

SELECT * FROM s3_access_logs_db.mybucket_logs
WHERE requester='arn:aws:iam::123456789123:user/user_name';

特定の期間中にオブジェクトに対して実行されたすべての操作を表示するには、次のクエリを使用します:

SELECT *FROM s3_access_logs_db.mybucket_logs WHERE Key='prefix/images/picture.jpg'  AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

特定の期間中に IP アドレスに転送されたデータ量を表示するには、次のクエリを使用します:

SELECT coalesce(SUM(bytessent), 0) AS bytessentTOTAL
FROM s3_access_logs_db.mybucket_logs
WHERE RemoteIP='1.2.3.4'AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

特定の期間中にライフサイクルルールによって実行された有効期限切れの操作をすべて表示するには、次のクエリを使用します:

SELECT * FROM s3_access_logs_db.mybucket_logs WHERE operation = 'S3.EXPIRE.OBJECT'
AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

特定の期間中に有効期限切れになったオブジェクトの数をカウントするには、次のクエリを使用します:

SELECT count(*) as ExpireCount FROM s3_access_logs_db.mybucket_logs
WHERE operation = 'S3.EXPIRE.OBJECT'
AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

特定の期間中にライフサイクルルールによって実行された移行の操作をすべて表示するには、次のクエリを使用します:

SELECT * FROM s3_access_logs_db.mybucket_logs
WHERE operation like 'S3.TRANSITION%'
AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

署名バージョン別にグループ化されたすべてのリクエスタを表示するには、次のクエリを使用します:

SELECT requester, Sigv, Count(Sigv) as SigCount
FROM s3_access_logs_db.mybucket_logs
GROUP BY requester, Sigv;

特定の期間中にリクエストを送信したすべての匿名リクエスタを表示するには、次のクエリを使用します:

SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE requester IS NULL AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

特定の期間中に PUT オブジェクトリクエストを送信したすべてのリクエスタを表示するには、次のクエリを使用します:

SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.PUT.OBJECT'
AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

特定の期間中に GET オブジェクトリクエストを送信したすべてのリクエスタを表示するには、次のクエリを使用します:

SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.GET.OBJECT'
AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'

ターンアラウンド時間が長い順に特定の期間中のすべてのリクエスタを表示するには、次のクエリを使用します:

SELECT * FROM s3_access_logs_db.mybucket_logs
WHERE NOT turnaroundtime='-'
AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'
ORDER BY CAST(turnaroundtime AS INT) DESC;

**注:**S3 バケット内のオブジェクト数は時間の経過とともに増加するため、クエリはより多くのデータを処理するようになります。サーバーアクセスログのバケット用のライフサイクルポリシーを作成するのがベストプラクティスです。ログファイルが定期的に削除されるようにライフサイクルポリシーを設定できます。これにより、各クエリで Athena が分析するデータの量を減らすことができます。

関連情報

Amazon OpenSearch Service で Amazon S3 サーバーのアクセスログを分析する

Amazon S3 サーバーアクセスログの形式

AWS サービスのログのクエリ

AWS公式
AWS公式更新しました 8ヶ月前