Athena Query SOP (athena_query_sop)
用途
通过浏览器访问 AWS Athena 控制台,查询 CloudFront 日志(Parquet 格式),排查 403/404 原因、WAF Block、流量异常等问题。
前置条件
- 浏览器已登录 AWS 控制台(有 Athena 权限)
- 使用 Kiro IDE 编辑器(基于 Ace Editor)
- 目标数据库(Catalog:
AwsDataCatalog, Database:default)
表结构
1. cloudfront_logs_parquet_pp_prod
CloudFront 标准日志表,Parquet 格式,按 year/month/day/hour 分区。
核心列:
| 列名 | 类型 | 说明 |
|---|---|---|
| date | string | 日志日期(如 2026-04-30) |
| time | string | 日志时间(如 00:28:52) |
| c_ip | string | 客户端 IP |
| cs_method | string | HTTP 方法(GET/POST 等) |
| cs_host | string | 请求的 Host 头 |
| cs_uri_stem | string | 请求路径(URL 路径部分) |
| cs_uri_query | string | 请求查询参数 |
| sc_status | string | HTTP 状态码(200/403/404 等) |
| sc_bytes | string | 响应字节数 |
| cs_user_agent | string | 客户端 User-Agent |
| cs_referer | string | 来源页面 URL |
| x_edge_location | string | CloudFront Edge 节点 |
| x_edge_result_type | string | 结果类型(Hit/Miss/Error 等) |
| x_edge_detailed_result_type | string | 详细结果类型 |
| x_edge_response_result_type | string | 响应结果类型 |
| x_edge_request_id | string | 请求 ID(可关联 WAF 日志) |
| time_taken | string | 请求耗时(秒) |
| time_to_first_byte | string | TTFB(秒) |
| cs_protocol | string | 协议(https/http) |
| cs_protocol_version | string | HTTP 协议版本 |
| ssl_protocol | string | SSL/TLS 协议版本 |
| ssl_cipher | string | SSL 加密套件 |
| c_port | string | 客户端端口 |
| distributionid | string | CloudFront Distribution ID |
| sc_content_type | string | 响应 Content-Type |
| sc_content_len | string | 响应内容长度 |
| fle_status | string | 字段级加密状态 |
| fle_encrypted_fields | string | 字段级加密字段 |
| x_forwarded_for | string | X-Forwarded-For 头 |
| x_host_header | string | 实际 Host 头 |
| cs_cookie | string | Cookie |
| sc_range_start | string | Range 请求起始 |
| sc_range_end | string | Range 请求结束 |
分区列(独立列,不在数据行中):
| 列名 | 说明 |
|---|---|
| year | 如 2026 |
| month | 如 5 |
| day | 如 6 |
| hour | 如 0~23 |
2. 视图(17 个视图)
视图名较长,通过
SHOW VIEWS获取完整列表。常见用途:
- 流量概览:按日期/状态码聚合的视图
- 慢查询分析:time_taken 较高的请求
- 4xx/5xx 统计:按路径/状态码聚合错误
- WAF 关联:可关联 WAF 日志的请求
关键经验
⚠️ 分区裁剪(最重要)
cloudfront_logs_parquet_pp_prod 的分区列是 year/month/day(三层独立列),不是 date 列。
正确写法(必须用分区列过滤,否则全表扫描超时):
WHERE year = '2026' AND month = '5' AND day = '6'
错误写法(会触发全表扫描,大概率超时):
WHERE date = '2026-05-06'
⚠️ Athena 不支持批量提交
每次只能执行一条 SQL。Ace Editor 需先清空再写入新 SQL。
⚠️ Ace Editor API
在 Kiro IDE 中,使用以下 JS 操作编辑器:
editor.setValue(yourSqlString);
然后点击 "Run" 按钮执行。
操作步骤
步骤 1:打开 Athena 控制台
- 浏览器访问 AWS 控制台 → 搜索 "Athena"
- 进入查询编辑器(Query Editor)
- 确认 Database 选择
default
步骤 2:检查表是否存在
SHOW TABLES IN default;
确认 cloudfront_logs_parquet_pp_prod 存在。
步骤 3:检查分区
SHOW PARTITIONS cloudfront_logs_parquet_pp_prod;
确认目标日期有数据分区。
步骤 4:编写查询(必遵守分区裁剪规则)
示例 1:查特定文件的 403/404 原因
SELECT
date,
time,
c_ip,
cs_method,
cs_uri_stem,
cs_uri_query,
sc_status,
sc_bytes,
cs_user_agent,
x_edge_result_type,
x_edge_detailed_result_type,
x_edge_response_result_type,
cs_referer
FROM cloudfront_logs_parquet_pp_prod
WHERE cs_uri_stem LIKE '%目标文件名.mp4%'
AND year = '2026' AND month = '5' AND day = '6'
ORDER BY time DESC
LIMIT 50;
示例 2:查某 IP 的所有请求
SELECT date, time, cs_method, cs_uri_stem, sc_status, x_edge_result_type
FROM cloudfront_logs_parquet_pp_prod
WHERE c_ip = 'x.x.x.x'
AND year = '2026' AND month = '5' AND day = '6'
ORDER BY time;
示例 3:统计某天各状态码数量
SELECT sc_status, COUNT(*) AS cnt
FROM cloudfront_logs_parquet_pp_prod
WHERE year = '2026' AND month = '5' AND day = '6'
GROUP BY sc_status
ORDER BY cnt DESC;
示例 4:查 WAF Block 的请求(x_edge_result_type = 'Error')
SELECT date, time, c_ip, cs_uri_stem, sc_status, x_edge_detailed_result_type, x_edge_request_id
FROM cloudfront_logs_parquet_pp_prod
WHERE x_edge_detailed_result_type LIKE '%Block%'
AND year = '2026' AND month = '5' AND day = '6'
ORDER BY time DESC;
示例 5:查慢请求(耗时 > 5 秒)
SELECT date, time, c_ip, cs_uri_stem, sc_status, time_taken, x_edge_location
FROM cloudfront_logs_parquet_pp_prod
WHERE CAST(time_taken AS DOUBLE) > 5.0
AND year = '2026' AND month = '5' AND day = '6'
ORDER BY CAST(time_taken AS DOUBLE) DESC;
步骤 5:执行查询
- 将 SQL 写入 Ace Editor(如用自动化,通过
editor.setValue(sql)设置) - 点击 "Run" 按钮(或 Ctrl+Enter)
- 等待结果(通常 2-10 秒,分区裁剪好则快)
步骤 6:结果分析
- 403:多为 WAF Block 或签名验证失败。检查
x_edge_detailed_result_type,若含Block则关联 WAF 日志 - 404:文件不存在或路径错误。检查
cs_uri_stem和 Distribution 配置 - Error:CloudFront 内部错误,检查
x_edge_result_type - 大量 499:客户端提前断开连接
视图查询
查所有视图
SHOW VIEWS IN default;
查视图结构
DESCRIBE <view_name>;
查视图定义
SHOW CREATE VIEW <view_name>;
高级技巧
1. 时间范围查询(跨天)
SELECT date, COUNT(*) AS req_count
FROM cloudfront_logs_parquet_pp_prod
WHERE year = '2026' AND month = '5'
AND day BETWEEN '1' AND '7'
GROUP BY date
ORDER BY date;
2. 按小时聚合
SELECT hour, sc_status, COUNT(*) AS cnt
FROM cloudfront_logs_parquet_pp_prod
WHERE year = '2026' AND month = '5' AND day = '6'
GROUP BY hour, sc_status
ORDER BY hour, sc_status;
3. 查 Top N 热门路径
SELECT cs_uri_stem, COUNT(*) AS hits
FROM cloudfront_logs_parquet_pp_prod
WHERE year = '2026' AND month = '5' AND day = '6'
GROUP BY cs_uri_stem
ORDER BY hits DESC
LIMIT 20;
4. 用 x_edge_request_id 关联 WAF 日志
-- 先查出一条请求的 request_id
SELECT x_edge_request_id, date, time, c_ip, cs_uri_stem, sc_status
FROM cloudfront_logs_parquet_pp_prod
WHERE year = '2026' AND month = '5' AND day = '6'
AND sc_status = '403'
AND x_edge_detailed_result_type LIKE '%Block%'
LIMIT 5;
-- 然后用 x_edge_request_id 去 WAF 日志表关联查询
常见问题
Q: 查询超时怎么办?
A: 检查是否忘了分区裁剪!必须用 year/month/day 过滤。视图本身可能已有分区过滤,但自定义 SQL 必须加。
Q: 查不出来数据?
A: 三步排查:① SHOW PARTITIONS 确认分区存在 ② SELECT * FROM table WHERE year='...' AND month='...' AND day='...' LIMIT 5 确认能查到数据 ③ 检查条件拼写
Q: 怎么查最新数据?
A: 先查分区找到最新日期:SHOW PARTITIONS cloudfront_logs_parquet_pp_prod,看到最新分区后再查。
Q: 怎么获取列名?
A: DESCRIBE cloudfront_logs_parquet_pp_prod;
自动化集成
- 通过
tmwebdriver_sop(TMWebDriver)在浏览器中操作 Athena 控制台 - Ace Editor 注入 SQL:
editor.setValue("SELECT ...") - 点击 "Run" 按钮执行
- 读取结果区域获取返回数据
参考
- 表列结构:详见
athena_columns.txt - 示例 SQL:详见
athena_query.sql - Athena 分区最佳实践:始终用分区列(year/month/day)过滤