本文介绍在一个CloudFront发布点绑定多个CNAME时候,如何使用Athena查询CloudFront日志以获得不同CNAME的流量分布。
一、背景
1、关于CNAME自定义域名
在使用CloudFront发布点的时候,每个发布点都有一个唯一的CloudFront自动分配的域名,例如dxxxxxxxxx.cloudfront.net
的格式,这个域名可以很直接发起HTTPS访问,可以被嵌入应用程序调用。为了使用自己的域名,可在CloudFront上绑定CNAME别名,这也被叫做自定义域名,例如web01.abc.com
,这样就可以使用用户自己的域名对CDN发布点进行访问。
这里需要注意,即便绑定了自定义域名web01.abc.com
,系统自动分配的dxxxxxxxxx.cloudfront.net
域名还是可以被访问的,它是一直有效的。不过,只要不把这个自动分配的域名公开,它是不会产生流量的。因此,所有的流量都会来自于web01.abc.com
。
2、绑定多个CNAME自定义域名时候的日志分析场景
如果一个CDN发布点只绑定了一个自定义域名,并且系统自动分配的dxxxxxxxxx.cloudfront.net
也没有对外发布,那么分析日志的时候,本CDN发布点的所有流量都会是自定义域名产生的。这时候可在CloudFront界面的Usage菜单下,可看到本发布点的日志流量总和。如下截图。
一个CDN发布点支持绑定多个CNAME自定义域名,例如一个CDN发布点绑定web01.abc.com
和image01.abc.com
两个域名。此时就有了日志分析的需求,如何根据不同的域名来统计流量,如何分别获取web01
和image01
哪一个流量高哪一个低。这时候使用Athena查询CloudFront的日志来确定用量。
二、打开CloudFront日志
进入CloudFront服务控制点,找到要打开日志的发布点,点击进入发布点详情。在General
标签页下方,可以看到在Alternate domain names
备用域名下,有两个绑定上的自定义域名,下一步就是打开日志。在Settings
位置点击Edit
。如下截图。
将页面向下滚动,在Standard logging
标准日志位置,把开关设置为On
。在下方输入CloudFront日志要输出的S3存储桶。这里建议使用一个独立的存储桶(建议把存储桶创建在美东1、美西2、法兰克福、新加坡区域)。如果是配置了多个CDN发布点都使用同一个S3存储桶保存日志,那么可以设置Prefix
前缀即子目录,通过子目录来区分。如下截图。
点击保存后,打开日志功能完成。
现在对本CDN发布点做一些访问请求。CloudFront的Standard Log一般需要等待5-10分钟后,才能在S3存储桶内看到日志。如下截图。
将日志下载到本地,使用文本编辑器打开,可以看到这个文件是CSV格式的,以空格作为隔离符号,其中的字段sc-bytes
是传输的字节数,字段x-host-header
是本次访问使用的域名。如果所有访问都是通过CloudFront自己分配的dxxxxxxxxx.cloudfront.net
的格式来访问的,那么这个x-host-header
就会显示CloudFront分配的域名。如果访问是使用了自定义域名CNAME来访问,那么这里就会显示本次访问使用的CNAME的名字。如下截图。
日志格式样本如下:
#Version: 1.0
#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes time-taken x-forwarded-for ssl-protocol ssl-cipher x-edge-response-result-type cs-protocol-version fle-status fle-encrypted-fields c-port time-to-first-byte x-edge-detailed-result-type sc-content-type sc-content-len sc-range-start sc-range-end
2024-03-18 05:37:43 HKG60-C1 757612 13.248.48.10 GET d51vuyprlknbq.cloudfront.net /APIGW/log/apigw-log-01.png 200 - Mozilla/5.0%20(Macintosh;%20Intel%20Mac%20OS%20X%2010_15_7)%20AppleWebKit/605.1.15%20(KHTML,%20like%20Gecko)%20Version/17.3.1%20Safari/605.1.15 - - Miss lepa9BqJcfUuxXihUsrvmqIqguWiGw7ec1SmYmaqj7X6StCe8vkoMg== myworkshop.bitipcman.com https 283 0.524 - TLSv1.3 TLS_AES_128_GCM_SHA256 Miss HTTP/2.0 - - 9469 0.296 Miss image/png 756274 - -
2024-03-18 05:37:44 HKG60-C1 15510 13.248.48.10 GET d51vuyprlknbq.cloudfront.net /favicon.ico 200 https://myworkshop.bitipcman.com/APIGW/log/apigw-log-01.png Mozilla/5.0%20(Macintosh;%20Intel%20Mac%20OS%20X%2010_15_7)%20AppleWebKit/605.1.15%20(KHTML,%20like%20Gecko)%20Version/17.3.1%20Safari/605.1.15 - - Miss 6UUfUNdTZe0dvwv-zJ0WjGRGePnKA_c8JpOhHjBUnFg9vIOtWvy1Hg== myworkshop.bitipcman.com https 102 0.292 - TLSv1.3 TLS_AES_128_GCM_SHA256 Miss HTTP/2.0 - - 9469 0.292 Miss image/x-icon 15086 - -
现在使用Athena进行下一步查询。
三、使用Athena分析CloudFront日志按CNAME统计流量
1、本账号/本区域首次使用Athena用户的初始化配置
选择上一步的S3存储桶所在的Region,进入Athena服务控制台。如下截图。
进入Athena服务后,从左侧菜单找到Workgroups
工作组设置。在2024年上半年,如果您在不同区域使用Athena,可能会遇到左侧菜单不一致的情况,这是由于各区域的Athena版本不一样。找到Workgroups后,点击进入,其中有一条是默认的Primary
。点击进入。如下截图。
在工作组Primary
的详情界面,可查看Query result location
设置,这是Athena查询结果集所使用的S3存储桶,Athena查询结果会保存在这里。这个选项在第一次使用Athena时候必须设置好。点击Edit
按钮进行配置。如下截图。
在Query result location
设置位置,输入S3存储桶用来保存Athena查询结果。这个存储桶要与之前的CloudFront日志的存储桶独立开,并且也是在Athena运行所在的区域。将事先创建好的存储桶填写进去。如下截图。
Athena首次设置设置完毕。
2、创建Athena表
在Athena界面上点击左侧的Query Editor
按钮,在确认右侧的Database
是选择了默认的default
数据库,在查询Query部分输入如下的SQL脚本。
CREATE EXTERNAL TABLE IF NOT EXISTS default.cloudfront_logs (
`date` DATE,
time STRING,
x_edge_location STRING,
sc_bytes BIGINT,
c_ip STRING,
cs_method STRING,
cs_host STRING,
cs_uri_stem STRING,
sc_status INT,
cs_referrer STRING,
cs_user_agent STRING,
cs_uri_query STRING,
cs_cookie STRING,
x_edge_result_type STRING,
x_edge_request_id STRING,
x_host_header STRING,
cs_protocol STRING,
cs_bytes BIGINT,
time_taken FLOAT,
x_forwarded_for STRING,
ssl_protocol STRING,
ssl_cipher STRING,
x_edge_response_result_type STRING,
cs_protocol_version STRING,
fle_status STRING,
fle_encrypted_fields INT,
c_port INT,
time_to_first_byte FLOAT,
x_edge_detailed_result_type STRING,
sc_content_type STRING,
sc_content_len BIGINT,
sc_range_start BIGINT,
sc_range_end BIGINT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LOCATION 's3://my-cloudfront-log-bucket/mydir/'
TBLPROPERTIES ( 'skip.header.line.count'='2' )
以上脚本中,需要替换S3存储桶的名称,然后点击Run
按钮即可执行脚本。如下截图。
脚本执行完毕,可看到数据库创建成功。
3、查询特定CNAME的流量总和
编辑如下SQL代码,然后提交执行。
SELECT ROUND(SUM(sc_bytes)*1.0/1024/1024,2) AS total_DTO_MB
FROM default.cloudfront_logs
WHERE "x_host_header"='myworkshop.bitipcman.com';
在以上代码中,sc_byte
字段是DTO传输的字节数,乘以1.0可以将其转换为浮点数,然后通过SUM函数求和,通过ROUND函数保留两位小数,这样就可以换算其单位MB了。如果不这样做,因为其默认是sc_byte
是INT整数,在SQL运算中除法之后自动取整,结果就偏离很大,因此才使用这种表示方法做运算。如下截图。
4、一个发布点绑定多个CNAME时候分别求总和
如果一个发布点绑定了多个CNAME,希望针对所有CNAME求和,那么可以通过groupby函数来分别求和。
编辑如下SQL代码,然后提交执行。
SELECT "date" as LogDate,
"x_host_header" AS Hostname,
ROUND(SUM(sc_bytes) * 1.0 / 1024 / 1024, 2) AS total_DTO_MB
FROM default.cloudfront_logs
GROUP BY "date",
"x_host_header";
这样即可分别求出多个CNAME各自的流量总和。如下截图。
四、参考文档
CloudFront标准日志 – 字段定义说明
使用Athena查询CloudFront标准日志