

# CloudTrail 로그 쿼리 예제
<a name="query-examples-cloudtrail-logs"></a>

다음 예제는 CloudTrail 이벤트 로그에 대해 생성된 테이블에서 모든 익명(서명되지 않은) 요청을 반환하는 쿼리의 일부를 보여줍니다. 이 쿼리는 `useridentity.accountid`가 익명이고 `useridentity.arn`이 지정되지 않은 요청을 선택합니다.

```
SELECT *
FROM cloudtrail_logs
WHERE 
    eventsource = 's3.amazonaws.com' AND 
    eventname in ('GetObject') AND 
    useridentity.accountid = 'anonymous' AND 
    useridentity.arn IS NULL AND
    requestparameters LIKE '%[your bucket name ]%';
```

자세한 내용은 AWS Big Data Blog 게시물 [Analyze Security, Compliance, and Operational Activity Using AWS CloudTrail and Amazon Athena](https://aws.amazon.com/blogs/big-data/aws-cloudtrail-and-amazon-athena-dive-deep-to-analyze-security-compliance-and-operational-activity/)를 참조하세요.

## CloudTrail 로그에서 중첩 필드 쿼리
<a name="cloudtrail-logs-nested-fields"></a>

`userIdentity` 및 `resources` 필드는 중첩된 데이터 형식이기 때문에 이를 쿼리하려면 특수한 처리가 필요합니다.

`userIdentity` 객체는 중첩된 `STRUCT` 형식으로 구성됩니다. 다음 예에서처럼 점으로 필드를 구분하여 이 객체들을 쿼리할 수 있습니다.

```
SELECT 
    eventsource, 
    eventname,
    useridentity.sessioncontext.attributes.creationdate,
    useridentity.sessioncontext.sessionissuer.arn
FROM cloudtrail_logs
WHERE useridentity.sessioncontext.sessionissuer.arn IS NOT NULL
ORDER BY eventsource, eventname
LIMIT 10
```

`resources` 필드는 `STRUCT` 객체의 배열입니다. 이러한 배열의 경우 `CROSS JOIN UNNEST`를 사용해 배열의 중첩을 해제함으로써 해당 객체를 쿼리할 수 있습니다.

다음 예제는 리소스 ARN이 `example/datafile.txt`로 끝나는 모든 행을 반환합니다. [replace](https://prestodb.io/docs/current/functions/string.html#replace) 함수는 가독성을 위해 ARN에서 초기 `arn:aws:s3:::` 하위 문자열을 제거합니다.

```
SELECT 
    awsregion,
    replace(unnested.resources_entry.ARN,'arn:aws:s3:::') as s3_resource,
    eventname,
    eventtime,
    useragent
FROM cloudtrail_logs t
CROSS JOIN UNNEST(t.resources) unnested (resources_entry)
WHERE unnested.resources_entry.ARN LIKE '%example/datafile.txt'
ORDER BY eventtime
```

다음 예제에서는 `DeleteBucket` 이벤트를 쿼리합니다. 이 쿼리는 `resources` 객체에서 버킷의 이름 및 버킷이 속한 계정 ID를 추출합니다.

```
SELECT 
    awsregion,
    replace(unnested.resources_entry.ARN,'arn:aws:s3:::') as deleted_bucket,
    eventtime AS time_deleted,
    useridentity.username, 
    unnested.resources_entry.accountid as bucket_acct_id 
FROM cloudtrail_logs t
CROSS JOIN UNNEST(t.resources) unnested (resources_entry)
WHERE eventname = 'DeleteBucket'
ORDER BY eventtime
```

중첩 해제에 대한 자세한 내용은 [배열 필터링](filtering-arrays.md) 단원을 참조하세요.

## CloudTrail 로그 쿼리 팁
<a name="tips-for-querying-cloudtrail-logs"></a>

CloudTrail 로그 데이터를 탐색할 때 다음 사항을 고려하세요.
+ 로그를 쿼리하기 전에 로그 테이블이 [수동 분할을 사용하여 Athena에서 CloudTrail 로그용 테이블 생성](create-cloudtrail-table.md)의 로그 테이블과 동일한 형태인지 확인합니다. 첫 번째 테이블이 아닌 경우 `DROP TABLE cloudtrail_logs` 명령을 사용하여 기존 테이블을 삭제합니다.
+ 기존 테이블을 삭제하고 다시 만드세요. 자세한 내용은 [수동 분할을 사용하여 Athena에서 CloudTrail 로그용 테이블 생성](create-cloudtrail-table.md) 섹션을 참조하세요.

  Athena 쿼리의 필드가 올바르게 나열되는지 확인합니다. CloudTrail 레코드의 필드 전체 목록에 대한 자세한 내용은 [CloudTrail 레코드 콘텐츠](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html)를 참조하세요.

  쿼리에 `STRUCT` 같은 JSON 형식의 필드가 포함된 경우, JSON에서 데이터를 추출합니다. 자세한 내용은 [문자열에서 JSON 데이터 추출](extracting-data-from-JSON.md) 섹션을 참조하세요.

  다음은 CloudTrail 테이블에 대해 쿼리를 실행하기 위한 몇 가지 제안 사항입니다.
+ 먼저 어떤 사용자가 어떤 API 작업을 호출했으며 어떤 소스 IP 주소에서 시작되었는지 확인합니다.
+ 다음 기본 SQL 쿼리를 템플릿으로 사용합니다. 쿼리를 Athena 콘솔에 붙여 넣고 실행합니다.

  ```
  SELECT
   useridentity.arn,
   eventname,
   sourceipaddress,
   eventtime
  FROM cloudtrail_logs
  LIMIT 100;
  ```
+ 데이터를 추가 탐색하려면 쿼리를 수정합니다.
+ 성능을 향상시키려면 `LIMIT` 절을 포함시켜 지정한 행 하위 집합을 반환합니다.