Athena를 사용하여 AWS 로그 집계

AWS 로그(ELB, CloudFront, CloudTrail)를 S3에 저장하고 Athena에서 집계해 보았습니다.
DDL 정의도 포함되어 있습니다. 문서 기재의 것과 달리, 사용하기 쉬운 형태로 변경했습니다.

Athena 개요


  • S3에 저장된 데이터에 대해 쿼리를 실행할 수 있음
  • 인스턴스를 시작하지 않고 S3 데이터에 대해 직접 SQL 쿼리 실행 가능
  • ANSI SQL 지원
  • 내부적으로 Presto가 실행 중이므로 Presto에서 사용할 수있는 것은 대부분 사용할 수 있습니다
  • 요금은 쿼리 단위 1TB당 $5

  • 아직 버지니아와 오레곤에서만 사용할 수 있습니다.


  • 도쿄 지역에서는 아직 사용할 수 없습니다
  • Athena는 S3를 참조하므로 Athena (버지니아) → S3 (도쿄)로하면 미묘하게 느려집니다

  • 해보자



    데이터베이스 만들기


  • 먼저 데이터베이스 만들기
  • 기본 녀석이 될 수 있습니다

  • 샘플
    CREATE DATABASE aws_logs;
    



    테이블 만들기


  • GUI로도 입력 할 수 있지만 SQL을 작성합니다.
  • GUI에서 테이블 정의를 입력하는 것이 상당히 번거롭습니다
  • 다음은 DDL 정의입니다


  • ELB



    ELB
    CREATE EXTERNAL TABLE IF NOT EXISTS aws_logs.elb_log (
      request_protocol string,
      request_timestamp string,
      elb_name string,
      request_ip string,
      request_port int,
      backend_ip string,
      backend_port int,
      request_processing_time double,
      backend_processing_time double,
      client_response_time double,
      elb_response_code string,
      backend_response_code string,
      received_bytes bigint,
      sent_bytes bigint,
      request_verb string,
      url string,
      protocol string,
      user_agent string,
      ssl_cipher string,
      ssl_protocol string,
      arn string,
      extra string )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
    WITH SERDEPROPERTIES (
        'serialization.format' = '1','input.regex' = '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*):([0-9]*) (-1|[.0-9]*) (-1|[.0-9]*) (-1|[.0-9]*) (-|[0-9]*) (-|[0-9]*) ([-0-9]*) ([-0-9]*) \\\"([^ ]*) ([^ ]*) (- |[^ ]*)\\\" (\"[^\"]*\") ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*)$' )
    LOCATION 's3://*******/********/'
    

    CloudFront



    cloudfront
    CREATE EXTERNAL TABLE IF NOT EXISTS aws_logs.cloudfront_log (
      date STRING,
      time STRING,
      xEdgeLocation STRING,
      scBytes INT,
      cIp STRING,
      csMethod STRING,
      csHost STRING,
      csUriStem STRING,
      scStatus INT,
      csReferer STRING,
      csUserAgent STRING,
      csUriQuery STRING,
      csCookie STRING,
      xEdgeResultType STRING,
      xEdgeRequestId STRING,
      xHostHeader STRING,
      csProtocol STRING,
      csBytes INT,
      timeTaken INT,
      xForwardedFor STRING,
      sslProtocol STRING,
      sslCipher STRING,
      xEdgeResponseResultType STRING,
      csProtocolVersion STRING
    )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
    WITH SERDEPROPERTIES (
      'serialization.format' = '1','input.regex' = '([^ ]*)\t([^ ]*)\t([^ ]*)\t([0-9]*)\t([.0-9]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([0-9]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([0-9]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)\t([^ ]*)$'
    ) LOCATION 's3://****/******/'
    

    CloudTrail



    cloudtrail
    CREATE EXTERNAL TABLE IF NOT EXISTS sample.records (
      records ARRAY<STRUCT<eventTime:STRING,eventSource:STRING,eventName:STRING>>
    )
    ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
    WITH SERDEPROPERTIES (
      'serialization.format' = '1'
    ) LOCATION 's3://********/***/'
    

    SELECT하다


  • ANSI SQL 지원이므로 정상적으로 SQL을 실행하십시오
  • CloudFront 및 CloudTrail 만주의하십시오

  • CloudFront의 SELECT 참고 사항


  • 위의 DDL을 실행하면 일부 아무 것도 포함되지 않은 레코드가 생성됩니다.
  • CloudFront 로그 파일에는 처음 두 줄에 주석 및 헤더가 있습니다
  • 현재, Athena는 이것을 제외하고 캡처 할 수 없습니다
  • Presto에서 사용할 수있는 org.apache.hadoop.hive.serde2.OpenCSVSerde 사용할 수있게되기를 기다리십시오

  • select 할 때 where 절에 date NOT LIKE '#%'를 지정하도록합시다

  • sample-select
    SELECT count(*) 
    FROM aws_logs.cloudfront_log 
    WHERE date NOT LIKE '#%'
    

    CloudTrail의 SELECT 참고 사항


  • CloudTrail 로그는 JSON 형식이므로 열을 분리하는 것이 어렵습니다 (방법이 있다면 알려주세요)
  • select할 때는 다음과 같이 한다. 번거로운 ...

  • sample-trail-select
    SELECT record.eventTime
    FROM aws_logs.traillog
    CROSS JOIN unnest(records) AS t(record)
    WHERE record.eventname='ConsoleLogin' limit 10
    

    sample-trail-select2
    SELECT record
    FROM aws_logs.traillog
    CROSS JOIN unnest(records) AS t(record)
    WHERE record.eventtime LIKE '2017-02-08%' limit 10
    

    요약


  • ELB와 CloudFront의 로그를 넣는 것만으로 5XX 계열 오류 등의 조사가 상당히 쉬워집니다
  • Trail 로그는 또 한 걸음이네요. 깨끗하게 컬럼으로 넣으면 조사하기 쉽다.
  • 시간이 기본 UTC이므로 조금주의가 필요합니다
  • 좋은 웹페이지 즐겨찾기