如何用 Athena 分析 Amazon S3 服务器访问日志?

3 分钟阅读
0

我想在 Amazon Athena 中查询 Amazon Simple Storage Service (Amazon S3) 服务器访问日志。

解决方法

Amazon S3 将服务器访问日志作为对象存储在一个 S3 桶中。通过 Athena 快速分析和查询服务器访问日志。

1.    如尚未启用 S3 桶的服务器访问日志,则启用此功能。记下目标桶目标前缀的值。要在 Athena 查询中指定 Amazon S3 位置,您同时需要此二者。

2.    打开 Amazon Athena 控制台。运行第一次查询前,您可能需要执行 Athena 首次设置

3.    在查询编辑器中运行 DDL 语句,以此来创建数据库。最好是在与 S3 桶相同的 AWS 区域中创建数据库。

create database s3_access_logs_db

4.    在数据库中创建表架构。以下示例中,**STRING ** 和 BIGINT 数据类型值是访问日志属性。您可在 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)
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://awsexamplebucket1-logs/prefix/'

5.    在左侧窗格的下,从表格名称旁边的菜单按钮中选择预览表。如在结果窗口中看到来自服务器访问日志的数据,则表示成功创建了 Athena 表。这些数据看起来像数值,诸如 bucketownerbucket_namerequestdatetime)。您现在可以查询 Amazon S3 服务器访问日志。

查询示例

要查找对已删除对象的请求,请使用以下查询:

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

要显示导致 403 访问被拒绝错误的请求的 Amazon S3 请求 ID,请使用以下查询:

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

要查找 Amazon S3 在特定时间段内出现 HTTP 5xx 错误的请求 ID(包括密钥和错误代码),请运行以下查询:

SELECT requestdatetime, key, httpstatus, errorcode, requestid, hostid
FROM s3_access_logs_db.mybucket_logsWHERE httpstatus like '5%'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-09-18 07:00:00'
AND timestamp '2021-09-18 08:00:00'

要显示谁删除了对象以及何时删除的对象,包括时间戳、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_logsWHERE Key='prefix/images/picture.jpg'     
AND parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')    
BETWEEN timestamp '2021-09-18 07:00:00'    
AND timestamp '2021-09-18 08:00:00'

要显示在特定时间段内向 IP 地址传输了多少数据,请使用以下查询:

SELECT coalesce(SUM(bytessent), 0) AS bytessentTOTAL,
FROM s3_access_logs_db.mybucket_logs
WHERE RemoteIP='1.2.3.4'AND parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2020-01-01'
AND timestamp '2024-01-01'

要显示生命周期规则在特定时间段内执行的所有过期操作,请使用以下查询:

SELECT *FROM s3_access_logs_db.mybucket_logs
WHERE operation = 'S3.EXPIRE.OBJECT'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-09-18 00:00:00'
AND timestamp '2021-09-19 00:00:00'

要计算特定时间段内过期的对象数量,请使用以下查询:

SELECT count(*) as ExpireCount
FROM s3_access_logs_db.mybucket_logs
WHERE operation = 'S3.EXPIRE.OBJECT'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-09-18 00:00:00'
AND timestamp '2021-09-19 00:00:00'

要显示根据生命周期规则在特定时间段内执行的所有过渡操作,请使用以下查询:

SELECT \* FROM s3\_access\_logs\_db.mybucket\_logs
WHERE operation like 'S3.TRANSITION%'
AND parse\_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-09-18 00:00:00'
AND timestamp '2021-09-19 00:00:00'

要显示按签名版本分组的所有请求者,请使用以下查询:

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

要显示在特定时间段内发出请求的所有匿名请求者,请使用以下查询:

SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE requester IS NULL AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-07-01 00:42:42'
AND timestamp '2021-07-02 00:42:42'

要显示在特定时间段内发送 PUT 对象请求的所有请求者,请使用以下查询:

SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.PUT.OBJECT'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-07-01 00:42:42'
AND timestamp '2021-07-02 00:42:42'

要显示在特定时间段内发送 GET 对象请求的所有请求者,请使用以下查询:

SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.GET.OBJECT'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-07-01 00:42:42'
AND timestamp '2021-07-02 00:42:42'

要显示所有请求者(按特定时间段内的最高周转时间排序),请使用以下查询:

SELECT * FROM s3_access_logs_db.mybucket_logs
WHERE NOT turnaroundtime='-'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN timestamp '2021-07-01 00:42:42'
AND timestamp '2021-07-02 00:42:42'
ORDER BY CAST(turnaroundtime AS INT) DESC;

最佳做法是为您的服务器访问日志桶创建生命周期策略。配置生命周期策略以定期删除日志文件。这减少了 Athena 为每个查询分析的数据量。

相关信息

使用 Amazon OpenSearch 服务分析 Amazon S3 服务器访问日志

Amazon S3 服务器访问日志格式

查询 AWS 服务日志

AWS 官方
AWS 官方已更新 3 个月前