如何使用 Athena 分析我的 Amazon S3 服务器访问日志?
上次更新时间:2021 年 12 月 17 日
如何在 Amazon Athena 中查询 Amazon Simple Storage Service (Amazon S3) 服务器访问日志?
解决方法
Amazon S3 将服务器访问日志作为对象存储在 S3 存储桶中。您可以使用 Athena 快速分析和查询服务器访问日志。
1. 为您的 S3 存储桶启用服务器访问日志记录(如果尚未启用的话)。记下目标存储桶和目标前缀的值 - 您需要这两个值才能在 Athena 查询中指定 Amazon S3 位置。
2. 打开 Amazon Athena 控制台。
3. 在查询编辑器中,运行 DDL 语句以创建数据库:
注意:最佳实践是在与 S3 存储桶相同的 AWS 区域中创建数据库。
create database s3_access_logs_db
4. 在数据库中创建表架构。在以下示例中,STRING 和 BIGINT 数据类型值是访问日志属性。您可以在 Athena 中查询这些属性。对于位置,输入步骤 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. 在左侧窗格中的表下,从表名称旁边的菜单按钮中选择预览表。如果您在结果窗口中看到服务器访问日志中的数据 (例如 bucketowner、bucket、requestdatetime),您已成功创建了 Athena 表。您现在可以查询 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';
要查找特定时间段内 HTTP 5xx 错误的 Amazon S3 请求 ID(包括键和错误代码),请运行以下查询:
SELECT requestdatetime, key, httpstatus, errorcode, requestid, hostid FROM s3_access_logs_db.mybucket_logs
WHERE httpstatus like '5%' AND
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-09-18:07:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-18:08:00:00','yyyy-MM-dd:HH:mm:ss');
要显示谁删除了对象以及何时删除,包括时间戳、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 SUM(bytessent) as uploadtotal,
SUM(objectsize) as downloadtotal,
SUM(bytessent + objectsize) AS total 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 parse_datetime('2021-07-01','yyyy-MM-dd')
AND parse_datetime('2021-08-01','yyyy-MM-dd');
要显示在特定时间段内通过 IP 地址传输的数据量,请使用以下查询:
SELECT SUM(bytessent) as uploadtotal,
SUM(objectsize) as downloadtotal,
SUM(bytessent + objectsize) AS total 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 parse_datetime('2021-07-01','yyyy-MM-dd')
AND parse_datetime('2021-08-01','yyyy-MM-dd');
要显示生命周期规则在特定时间段内执行的所有过期操作,请使用以下查询:
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 parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss');
要统计特定时间段内过期的对象数,请使用以下查询:
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 parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss');
要显示生命周期规则在特定时间段内执行的所有转换操作,请使用以下查询:
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 parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss');
要显示按签名版本分组的所有请求者,请使用以下查询:
SELECT requester, Sigv, Count(Sigv) as SigCount
FROM s3_access_logs_db.mybucket_logs
GROUP BY requester, Sigv;
要显示在特定时间段内发出请求的所有匿名请求者,请使用以下查询:
SELECT Bucket, 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 parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
要显示在特定时间段内发送 PUT 对象请求的所有请求者,请使用以下查询:
SELECT Bucket, Requester, RemoteIP, Key, HTTPStatus, ErrorCode, RequestDateTime
FROM s3_access_logs_db
WHERE Operation='REST.PUT.OBJECT' AND
parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
要显示在特定时间段内发送 GET 对象请求的所有请求者,请使用以下查询:
SELECT Bucket, Requester, RemoteIP, Key, HTTPStatus, ErrorCode, RequestDateTime
FROM s3_access_logs_db
WHERE Operation='REST.GET.OBJECT' AND
parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
要显示在特定时间段内发出请求的所有匿名请求者,请使用以下查询:
SELECT Bucket, 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 parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
要显示所有请求者(按特定时间段内的最高周转时间排序),请使用以下查询:
SELECT * FROM s3_access_logs_db.mybucket_logs
NOT turnaroundtime='-' AND
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss')
ORDER BY CAST(turnaroundtime AS INT) DESC;
为服务器访问日志存储桶创建生命周期策略是最佳实践。配置生命周期策略以定期删除日志文件。这样做可以减少 Athena 为每个查询分析的数据量。