[AWS] Athena를 활용한 로그 분석하기

2020. 12. 30. 09:30AWS/AWS_Service

반응형

안녕하세요, 달콤한달팽이입니다.🐌🫡

 

AWS에서는 CloudTrail, ELB 등의 다양한 로그를 S3에 적재하도록 설정할 수 있습니다.

 

이를 통해 이슈가 발생했을 경우 원하는 기록을 사용하여 이를 분석할 수 있지만,

S3에는 단편적인 데이터가 압축파일로 저장되어 있어 이를 하나하나 다운 받기에는 어려움이 있습니다.

 

그래서 오늘은 AWS Athena를 사용하여 간단한 쿼리문을 사용하여 로그를 분석하는 방법에 대해 알아보겠습니다.


Athena란?

Athena란, 표준 SQL을 사용해 S3에 저장된 데이터를 분석할 수 있는 쿼리 서비스를 의미합니다.

 

Athena의 특징

1) 서버리스 아키텍처: Athena는 서버리스 아키텍처로 인해 별도 인프라 생성 없이 사용이 가능합니다.

2) 표준 SQL 지원: Athena는 표준 SQL을 지원하여 간편하게 S3 데이터 분석이 가능합니다.

3) 데이터 쿼리: SQL 쿼리문을 사용하여 S3의 데이터를 사용한 다양한 작업이 가능합니다.

4) 데이터 카탈로그: AWS Glue와 통합하여 메타 데이터 관리가 가능합니다.

 

이제 실제로 Athena를 사용하여 S3의 로그를 분석해보도록 하겠습니다.

 

이번 실습에서는 CloudTrail Logs와 ELB AccesLogs를 분석해보도록 하겠습니다.


1) Athena 기본 설정

Athena 서비스를 검색하면 바로 보이는 "쿼리 편집기 탐색"을 선택하여 Athena를 시작해주세요.

 

쿼리 편집기의 "설정 - 관리" 탭에서 Athena 결과값이 저장될 위치를 적용해주세요.

 

보유하고 있는 S3를 지정하고, 나머지는 공란으로 저장해주세요.

(해당 과정은 Optional이지만 등록해두지 않을 경우 쿼리문 실행이 불가능합니다..)

 

2) CloudTrail Logs 분석

이제 쿼리문에 테이블을 생성해보도록 하겠습니다.

 

아래의 쿼리문을 참고하여 테이블을 생성해주세요.

(cloudtrail_logs, LOCATION 파트는 수정이 필요해요!)

CREATE EXTERNAL TABLE IF NOT EXISTS cloudtrail_logs (
    eventversion STRING,
    useridentity STRUCT<
        type:STRING,
        principalid:STRING,
        arn:STRING,
        accountid:STRING,
        invokedby:STRING,
        accesskeyid:STRING,
        username:STRING,
        sessioncontext:STRUCT<
            attributes:STRUCT<
                mfaauthenticated:STRING,
                creationdate:STRING
            >,
            sessionissuer:STRUCT<  
                type:STRING,
                principalid:STRING,
                arn:STRING, 
                accountid:STRING,
                username:STRING
            >
        >
    >,
    eventtime STRING,
    eventsource STRING,
    eventname STRING,
    awsregion STRING,
    sourceipaddress STRING,
    useragent STRING,
    errorcode STRING,
    errormessage STRING,
    requestparameters STRING,
    responseelements STRING,
    additionaleventdata STRING,
    requestid STRING,
    eventid STRING,
    resources ARRAY<STRUCT<
        arn:STRING,
        accountid:STRING,
        type:STRING
    >>,
    eventtype STRING,
    apiversion STRING,
    readonly STRING,
    recipientaccountid STRING,
    serviceeventdetails STRING,
    sharedeventid STRING
)
ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://{S3 CloudTrail Bucket}/AWSLogs/{AWS ID}/CloudTrail/';

 

이제 해당 테이블에서 원하는 이벤트를 SQL을 사용하여 분석해보도록 하겠습니다.

 

이번 실습에서는 1월 15일 00시부터 1월 15일 14시까지 TerminateInstances 이벤트를 추출해보도록 하겠습니다.

SELECT 
    eventtime,
    eventname,
    useridentity.arn AS userArn,
    requestparameters,
    responseelements
FROM 
    "default"."cloudtrail_logs"
WHERE 
    date_parse(replace(eventtime, 'Z', ''), '%Y-%m-%dT%H:%i:%s')
    BETWEEN TIMESTAMP '2025-01-15 00:00:00'
    AND TIMESTAMP '2025-01-15 14:00:00'
    AND eventname IN ('TerminateInstances')

 

성공시 아래와 같은 결과물 추출됩니다.

 

이번 결과에서는 j로 시작하는 IAM Role이 i-0008xxx 인스턴스를 삭제했다는 것을 알 수 있습니다.

 

위 쿼리문에서 시간, 이벤트 이름 정도만 잘 수정하여 분석하면 큰 도움이 될 수 있을 것이라 생각합니다.

 

3) ELB AccessLogs 분석

ELB AccssLogs 역시 CloudTrail과 동일한 방식으로 수행됩니다.

 

아래와 같이 테이블을 생성해주세요.

CREATE EXTERNAL TABLE IF NOT EXISTS alb_access_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 int,
            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,
            conn_trace_id 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 경로}';

 

이제 해당 테이블에서 원하는 이벤트를 SQL을 사용하여 분석해보도록 하겠습니다.

 

이번 실습에서는 1월 14일 00시부터 1월 14일 14시까지 ELB 상태 코드가 400 이상이었던 이벤트를 추출해보도록 하겠습니다.

SELECT * FROM alb_access_logs
WHERE parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z') 
     BETWEEN parse_datetime('2025-01-14-00:00:00','yyyy-MM-dd-HH:mm:ss') 
     AND parse_datetime('2025-01-14-14:00:00','yyyy-MM-dd-HH:mm:ss') 
     AND CAST(elb_status_code AS INT) >= 400

 

 

성공시 아래와 같은 결과물 추출됩니다.

 

약 190건 정도 400 이상의 상태페이지를 출력한 결과가 있는 것을 확인할 수 있습니다.

 

위 쿼리문에서 상태코드만 잘 수정하여 분석하면 큰 도움이 될 수 있을 것이라 생각합니다.


실제 운영을 수행하며 장애가 발생할 경우,

재발을 막기위한 로그 분석은 필수 항목 중 하나라고 생각합니다.

 

이 글을 읽어보신 분들은 S3에 저장된 압축파일을 하나씩 다운받아가며 분석하는 노력을 줄이시고,

재빠른 장애대응을 수행하실 수 있으면 좋겠습니다.

 

감사합니다!

반응형