如何使用 Amazon Athena 分析我的 Application Load Balancer 访问日志?

上次更新时间:2021 年 5 月 24 日

我想要使用 Amazon Athena 分析自己的 Application Load Balancer 访问日志

简短描述

默认情况下,Elastic Load Balancing 不会启用访问日志记录。在您启用访问日志记录时,需要指定一个 Amazon Simple Storage Service (Amazon S3) 存储桶。所有 Application Load Balancer 和 Classic Load Balancer 访问日志都存储在该 S3 存储桶中。您希望进行问题排查或分析负载均衡器的性能时,可以使用 Athena 分析 S3 中的访问日志。

注意:虽然您可以使用 Athena 分析 Application Load Balancer 和 Classic Load Balancer 的访问日志,但本文仅介绍了 Application Load Balancer。

解决方法

为 Application Load Balancer 日志创建数据库和表

要在 Athena 中分析访问日志,请通过以下步骤创建数据库和表:

1.    打开 Athena 控制台

2.    在查询编辑器中,运行类似如下的命令以创建数据库。最佳实践是在 S3 存储桶所在的 AWS 区域创建数据库。

create database alb_db

3.    在上一步创建的数据库中,为 Application Load Balancer 日志创建表 alb_log。有关更多信息,请参阅为 Application Load Balancer 日志创建表

注意:若要实现更好的查询性能,您可以选择创建具有分区投影的表。在分区投影中,分区值和位置是根据配置计算的,而不是从存储库(如 AWS Glue 数据目录)中读取的。有关更多信息,请参阅使用 Amazon Athena 进行分区投影

CREATE EXTERNAL TABLE IF NOT EXISTS alb_log_partition_projection (
 type string,
 time string,
 elb string,
 client_ip string,
 target_ip string,
 target_port int,
 request_processing_time double,
 target_processing_time double,
 response_processing_time double,
 elb_status_code string,
 received_bytes bigint,
 sent_bytes bigint,
 request_verb string,
 request_url string,
 request_proto string,
 user_agent string,
 ssl_cipher string,
 ssl_protocol string,
 target_group_arn string,
 trace_id string,
 domain_name string,
 chosen_cert_arn string,
 matched_rule_priority string,
 request_creation_time string,
 actions_executed string,
 redirect_url string,
 error_reason string
)
PARTITIONED BY(year int, month int, day int)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1',
'input.regex' ='([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \"([^ ]*) ([^ ]*) (- |[^ ]*)\" \"([^\"]*)\" ([A-Z0-9-]+) ([A-Za-z0-9.-]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([-.0-9]*) ([^ ]*) \"([^\"]*)\" \"([^ ]*)\" \"([^ ]*)\"' )
LOCATION 's3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/'
TBLPROPERTIES (
 'has_encrypted_data'='false',
 'projection.day.digits'='2',
 'projection.day.range'='01,31',
 'projection.day.type'='integer',
 'projection.enabled'='true',
 'projection.month.digits'='2',
 'projection.month.range'='01,12',
 'projection.month.type'='integer',
 'projection.year.digits'='4',
 'projection.year.range'='2020,2021',
 'projection.year.type'='integer',
 "storage.location.template" = "s3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/${year}/${month}/${day}"
)

请务必根据您的使用案例放替换表名称和 S3 位置。

您可以创建带有分区的表,并使用 AWS Glue 抓取程序或 ALTER TABLE ADD PARTITION 命令将它们加载到表中。

CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs_partitioned (
 type string,
 time string,
 elb string,
 client_ip string,
 client_port int,
 target_ip string,
 target_port int,
 request_processing_time double,
 target_processing_time double,
 response_processing_time double,
 elb_status_code string,
 target_status_code string,
 received_bytes bigint,
 sent_bytes bigint,
 request_verb string,
 request_url string,
 request_proto string,
 user_agent string,
 ssl_cipher string,
 ssl_protocol string,
 target_group_arn string,
 trace_id string,
 domain_name string,
 chosen_cert_arn string,
 matched_rule_priority string,
 request_creation_time string,
 actions_executed string,
 redirect_url string,
 error_reason string
 )
 PARTITIONED BY (year string, month string, day string)
 ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
 WITH SERDEPROPERTIES (
 'serialization.format' = '1',
 'input.regex' =
 '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \"([^ ]*) ([^ ]*) (- |[^ ]*)\" \"([^\"]*)\" ([A-Z0-9-]+) ([A-Za-z0-9.-]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([-.0-9]*) ([^ ]*) \"([^\"]*)\" \"([^ ]*)\" \"([^ ]*)\"' )
 LOCATION 's3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/';
ALTER TABLE alb_logs_partitioned ADD
  PARTITION (year = '2020', month ='05', day= '21')
  LOCATION's3://my_log_bucket/AWSLogs/1111222233334444/elasticloadbalancing/us-east-1/2020/05/21/'

4.     在导航窗格中的下,从表名称旁边的菜单按钮中选择预览表结果窗口中会显示 Application Load Balancer 访问日志中的数据。

5.    使用查询编辑器,对表运行 SQL 语句。您可以保存查询、查看以前的查询或下载 CSV 格式的查询结果。

示例查询

在下面的示例中,请务必修改表名称、列值和其他变量,以适合您的查询。

操作 查询

按时间顺序查看前 100 个访问日志条目。

使用案例:分析和问题排查

SELECT *
FROM alb_log
ORDER by time ASC
LIMIT 100;

列出所有已访问 Application Load Balancer 的客户端 IP 地址,以及它们访问 Application Load Balancer 的次数。

使用案例:分析和问题排查

SELECT distinct client_ip, count() as count from alb_log
GROUP by client_ip
ORDER by count() DESC;

列出请求/响应对中通过 Application Load Balancer 传输的平均数据量(以 KB 为单位)。

使用案例:分析和问题排查

SELECT (avg(sent_bytes)/1000.0 + avg(received_bytes)/1000.0)
as prewarm_kilobytes from alb_log;

列出 Application Load Balancer 将流量路由到的所有目标,以及 Application Load Balancer 按百分比分配形式,将请求路由到每个目标的次数。

使用案例:识别潜在的目标流量不平衡

SELECT target_ip, (Count(target_ip)* 100.0 / (Select Count(*) From alb_log))
as backend_traffic_percentage
FROM alb_log
GROUP by target_ip
ORDER By count() DESC;

列出客户端将请求发送到 Application Load Balancer,然后在空闲超时过期时间前终止与 Application Load Balancer 连接的次数(HTTP 460 错误)。

使用案例:纠正 HTTP 460 错误

SELECT * from alb_log where elb_status_code = '460';

列出因侦听器规则将请求转发给空的目标组而无法路由客户机请求的次数(HTTP 503 错误)。

使用案例:纠正 HTTP 503 错误

SELECT * from alb_log where elb_status_code = '503';

按照每个客户端访问指定 URL 的次数以降序顺序列出客户端。

使用案例:分析流量模式

SELECT client_ip, elb, request_url, count(*) as count from alb_log
GROUP by client_ip, elb, request_url
ORDER by count DESC;

按降序顺序列出 Firefox 用户最频繁访问的 10 个 URL。

使用案例:分析流量分配和模式

SELECT request_url, user_agent, count(*) as count
FROM alb_log
WHERE user_agent LIKE '%Firefox%'
GROUP by request_url, user_agent
ORDER by count(*) DESC
LIMIT 10;

按照每个客户端发送给 Application Load Balancer 的请求中包含的数据量(以 MB 为单位),以降序顺序列出客户端。

使用案例:分析流量分配和模式

SELECT client_ip, sum(received_bytes/1000000.0) as client_datareceived_megabytes
FROM alb_log
GROUP by client_ip
ORDER by client_datareceived_megabytes DESC;

列出指定日期范围内每次目标处理时间超过 5 秒的时间。

使用案例:解决指定的时间范围内的延迟问题

SELECT * from alb_log
WHERE (parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z')
     BETWEEN parse_datetime('2018-08-08-00:00:00','yyyy-MM-dd-HH:mm:ss')
     AND parse_datetime('2018-08-08-02:00:00','yyyy-MM-dd-HH:mm:ss'))
AND (target_processing_time >= 5.0);

对负载均衡器(按客户端 IP 地址分组)接收的 HTTP GET 请求数量进行计数。

使用案例:分析传入流量分配

SELECT COUNT(request_verb) AS count, request_verb, client_ip FROM alb_log_partition_projection WHERE year = '2020' AND month = '05' AND day = '21' GROUP BY request_verb, client_ip;  

这篇文章对您有帮助吗?


您是否需要账单或技术支持?