AWS Athena 로그 확인
AWS Athena를 활용한 쿼리로 로그 질의하기
2021-11-09 16:08
본 포스팅은 제가 노션에 2021년 07월에 정리한 것을 최대한 정리를 하여서 회사 개발 블로그에 정리한 내용입니다. 부족하더라도 이해해주세요. 감사합니다.
여러분 안녕하세요 글로우픽에서 백 엔드 개발을 맡은 김대성입니다. 생각보다 블로그로 자주 인사드리게 되네요 :) 오늘은 저희 쪽 AWS ELB 액세스 로그를 가지고 Athena에서 로그 내역 쿼리로 확인하는 글을 써볼까 합니다. 이미 예전에 급할 때 주로 쓰다가 이참에 정리하고 이 글을 쓰게 되었습니다. 🤔
Athena란?
Amazon Athena는 표준 SQL을 사용해 Amazon S3에 저장된 데이터를 간편하게 분석할 수 있는 대화식 쿼리 서비스입니다.
Athena는 사용이 쉽습니다. Amazon S3에 저장된 데이터를 가리키고 스키마를 정의한 후 표준 SQL을 사용하여 질의를 시작하기만 하면 됩니다. 그러면 대부분 결과가 수 초 이내에 제공됩니다. Athena에서는 데이터 분석을 준비하기 위한 복잡한 ETL 작업이 필요 없습니다. 따라서 SQL을 다룰 수 있는 사람은 누구나 신속하게 대규모 데이터 세트를 분석할 수 있습니다.
공식 사이트에서는 설명이 이렇게 잘되어 있습니다.
Athena 도입 배경
ELB에서 자체적인 로그는 활성화였지만 필요한 시점에서 장애든 지속적인 요청이슈이든 급하게 처리할 때가 필요할 때 단순 ELB 액세스 로그를 일일이 사용자가 파악하지 않고 AWS에서 기존 로그 파일을 가지고 데이터 질의를 날릴 수 있는 서비스가 있다고 해서 도입하게 되었습니다.
Athena 사전 셋팅
1.로드 밸런서 속성 편집
먼저 로드 밸런서의 액세스 로그를 활성화를 하여야 합니다. 로그 위치는 지정할 수 있으니 참고하시면 됩니다.
2.Athena 권한
저희는 일단 테스트를 할 예정이라 먼저 AthenaFullAccess로 먼저 주었습니다. 추후에 권한은 수정을 하셔야합니다.
3.Athena 쿼리 에디터로 가서 테이블을 생성
데이터베이스 생성
create database elb_db;
테이블 생성
CREATE EXTERNAL TABLE IF NOT EXISTS elb_glowpick_net_logs (
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,
new_field 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]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\s]+)\" \"([^\s]+)\"(.*)')
LOCATION 's3:로그경로';
elb에서 실제로 액세스 로그에 쌓을때 필요한 항목들을 이렇게 athena 테이블에 명시해줍니다. 자세한 항목에 대한 설명은 Athena Create-Table 참고하시면 됩니다.
파티션 데이터 밀어넣는법
ALTER TABLE elb_db.elb_glowpick_net_logs add partition (year="2020", month="07", day="10")
location "로그경로/2020/07/10";
공식 문서 -> 파티션에서는 이렇게 정의되어 있습니다.
테이블에 대해 하나 이상의 파티션 열을 만듭니다. 각 파티션은 하나 이상의 개별 열 이름/값 조합으로 구성됩니다 지정된 각각의 조합에 별개의 데이터 디렉터리가 생성되어 상황에 따라 쿼리 성능을 개선할 수 있습니다. 분할된 열은 테이블 데이터 자체 내에 존재하지 않으므로 테이블 자체의 열과 이름이 같은 열 이름을 사용하면 오류가 발생합니다. 자세한 내용은 데이터 파티셔닝을 참조
쿼리 예시
select
type,
time,
elb,
client_ip,
client_port,
target_ip,
target_port,
elb_status_code,
request_verb,
request_url,
user_agent
from elb_glowpick_net_logs
where regexp_like(elb,'admin')
ORDER BY time desc LIMIT 5;
결과
팁으로 기간별로 파티션 밀어넣을때는
ALTER TABLE elb_db.elb_api_j_glowpick_com_logs ADD
PARTITION (year='2020',month='09',day='01') LOCATION 's3://elb-access-log.glowpick/api-j.glowpick.com/AWSLogs/436582069789/elasticloadbalancing/ap-northeast-2/2020/09/01'
PARTITION (year='2020',month='09',day='30') LOCATION 's3://elb-access-log.glowpick/api-j.glowpick.com/AWSLogs/436582069789/elasticloadbalancing/ap-northeast-2/2020/09/30';
마치며
요즘은 AWS OpenSearch에서도 로그 자체를 확인할 수 있게 세팅되어있지만 이렇게 s3 액세스 로그로 Athena를 활용한 데이터 질의를 질의할 수 있다는 거 자체에 급할 때 쓸만한 것 같습니다. 😀