Amazon Athena를 사용하여 Application Load Balancer 액세스 로그를 분석하려면 어떻게 해야 하나요?

최종 업데이트 날짜: 2021년 6월 29일

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,
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,
lambda_error_reason string,
target_port_list string,
target_status_code_list string,
classification string,
classification_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]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\s]+?)\" \"([^\s]+)\" \"([^ ]*)\" \"([^ ]*)\"')
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 위치를 바꿔야 합니다.

다음 쿼리를 사용하여 파티션이 있는 테이블을 만들고 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,
lambda_error_reason string,
target_port_list string,
target_status_code_list string,
classification string,
classification_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]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\s]+?)\" \"([^\s]+)\" \"([^ ]*)\" \"([^ ]*)\"')
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/'

참고: Application Load Balancer 로그에 AWS Glue 크롤러를 사용하는 것은 모범 사례가 아닙니다.

4.     탐색 창의 [테이블(Tables)]에서 테이블 이름 옆에 있는 메뉴 버튼에서 [테이블 미리 보기(Preview table)]를 선택합니다. Application Load Balancer 액세스 로그의 데이터는 [결과(Results)] 창에 표시됩니다.

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를 통과하는 평균 데이터 용량(킬로바이트 단위)을 나열합니다.

사용 사례: 분석 및 문제 해결

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

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에 대한 요청으로 보낸 데이터 용량(메가바이트 단위)에 따라 클라이언트를 내림차순으로 나열합니다.

사용 사례: 트래픽 배포 및 패턴 분석

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;

이 문서가 도움이 되었나요?


결제 또는 기술 지원이 필요하세요?