

# API Gateway에서 REST API에 대한 CloudWatch 로깅 설정
<a name="set-up-logging"></a>

 요청 실행 또는 API에 대한 클라이언트 액세스와 관련된 문제를 디버깅하기 위해 Amazon CloudWatch Logs를 활성화하여 API 호출을 로깅할 수 있습니다. CloudWatch에 대한 자세한 내용은 [Amazon CloudWatch 지표를 사용한 REST API 실행 모니터링](monitoring-cloudwatch.md) 단원을 참조하십시오.

## API Gateway에 대한 CloudWatch 로그 형식
<a name="apigateway-cloudwatch-log-formats"></a>

 CloudWatch의 API 로깅에는 실행 로깅과 액세스 로깅이라는 두 가지 유형이 있습니다. 실행 로깅에서 API Gateway는 CloudWatch Logs를 관리합니다. 이 프로세스에는 로그 그룹 및 로그 스트림을 생성하는 작업과 호출자의 요청 및 응답을 로그 스트림에 보고하는 작업이 포함됩니다.

로깅된 데이터에는 오류 또는 실행 추적(예: 요청 또는 응답 파라미터 값 또는 페이로드), Lambda 권한 부여자(이전에는 사용자 지정 권한 부여자라고 함)가 사용하는 데이터, API 키가 필요한지 여부, 사용량 계획이 활성화되는지 여부 및 기타 정보가 포함됩니다. API Gateway는 로깅된 데이터에서 권한 부여 헤더, API 키 값 및 유사한 민감한 요청 파라미터를 삭제합니다.

보안 태세를 개선하려면 `ERROR` 또는 `INFO` 수준에서 실행 로깅을 사용하는 것이 좋습니다. 다양한 규정 준수 프레임워크를 준수하기 위해 이 작업을 수행해야 할 수 있습니다. 자세한 내용은 *AWS Security Hub 사용 설명서*에서 [Amazon API Gateway 제어](https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html)를 참조하세요.

API를 배포하면 API Gateway는 로그 그룹을 생성하고 로그 그룹 아래에 로그 스트림을 생성합니다. 로그 그룹은 `API-Gateway-Execution-Logs_{rest-api-id}/{stage_name}` 형식에 따라 명명됩니다. 로그는 각 로그 그룹 내에서 로그 스트림으로 다시 나뉘며, 로그 스트림은 로깅된 데이터가 보고될 때 **마지막 이벤트 시간** 기준으로 정렬됩니다.

액세스 로깅에서 API 개발자가 원하는 것은 누가 API에 액세스했고 호출자가 API에 어떻게 액세스했는지 로깅하는 것입니다. 자체 로그 그룹을 생성하거나 API Gateway에서 관리할 수 있는 기존 로그 그룹을 선택할 수 있습니다. 액세스 세부 정보를 지정하려면 [`$context`](api-gateway-variables-for-access-logging.md) 변수, 로그 형식 및 로그 그룹 대상을 선택합니다.

액세스 로그 형식에는 최소한 `$context.requestId` 또는 `$context.extendedRequestId`가 포함되어야 합니다. 로그 형식엥서 `$context.requestId` 및 `$context.extendedRequestId`를 포함하는 것이 가장 좋습니다.

**`$context.requestId`**  
이렇게 하면 `x-amzn-RequestId` 헤더에 값이 기록됩니다. 클라이언트는 `x-amzn-RequestId` 헤더의 값을 범용 고유 식별자(UUID) 형식의 값으로 재정의할 수 있습니다. API Gateway는 `x-amzn-RequestId` 응답 헤더에서 이 요청 ID를 반환합니다. API 게이트웨이는 액세스 로그에서 UUID 형식이 아닌 재정의된 요청 ID를 `UUID_REPLACED_INVALID_REQUEST_ID`로 대체합니다.

**`$context.extendedRequestId`**  
확장 요청 ID는 API Gateway가 생성하는 고유한 ID입니다. API Gateway는 `x-amz-apigw-id` 응답 헤더에서 이 요청 ID를 반환합니다. API 호출자는 이 요청 ID를 제공하거나 재정의할 수 없습니다. API 문제 해결에 도움이 되도록 AWS Support에 이 값을 제공해야 할 수도 있습니다. 자세한 내용은 [API Gateway에 대한 액세스 로깅 변수](api-gateway-variables-for-access-logging.md) 섹션을 참조하세요.

[Common Log Format](https://httpd.apache.org/docs/current/logs.html#common)(CLF), JSON, XML 또는 CSV 같은 분석 백엔드도 채택하는 로그 형식을 선택하십시오. 그러면 액세스 로그를 분석 백엔드에 직접 피드하여 지표를 계산하고 렌더링할 수 있습니다. 로그 형식을 정의하려면 [단계](https://docs.aws.amazon.com/apigateway/latest/api/API_Stage.html)의 [accessLogSettings/destinationArn](https://docs.aws.amazon.com/apigateway/latest/api/API_Stage.html#destinationArn) 속성에서 로그 그룹 ARN을 설정합니다. CloudWatch 콘솔에서 로그 그룹 ARN을 얻을 수 있습니다. 액세스 로그 형식을 정의하려면 [단계](https://docs.aws.amazon.com/apigateway/latest/api/API_Stage.html)의 [accessLogSetting/format](https://docs.aws.amazon.com/apigateway/latest/api/API_Stage.html#format) 속성에서 선택한 형식을 설정합니다.

일반적으로 사용되는 몇 가지 액세스 로그 형식의 예가 API Gateway 콘솔에 표시되며 다음과 같이 나열됩니다.
+ `CLF`([Common Log Format](https://httpd.apache.org/docs/current/logs.html#common)):

  ```
  $context.identity.sourceIp $context.identity.caller $context.identity.user [$context.requestTime]"$context.httpMethod $context.resourcePath $context.protocol" $context.status $context.responseLength $context.requestId $context.extendedRequestId
  ```
+  `JSON`: 

  ```
  { "requestId":"$context.requestId", "extendedRequestId":"$context.extendedRequestId","ip": "$context.identity.sourceIp", "caller":"$context.identity.caller", "user":"$context.identity.user", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod", "resourcePath":"$context.resourcePath", "status":"$context.status", "protocol":"$context.protocol", "responseLength":"$context.responseLength" }
  ```
+ `XML`: 

  ```
  <request id="$context.requestId"> <extendedRequestId>$context.extendedRequestId</extendedRequestId> <ip>$context.identity.sourceIp</ip> <caller>$context.identity.caller</caller> <user>$context.identity.user</user> <requestTime>$context.requestTime</requestTime> <httpMethod>$context.httpMethod</httpMethod> <resourcePath>$context.resourcePath</resourcePath> <status>$context.status</status> <protocol>$context.protocol</protocol> <responseLength>$context.responseLength</responseLength> </request>
  ```
+ `CSV`(쉼표로 분리된 값):

  ```
  $context.identity.sourceIp,$context.identity.caller,$context.identity.user,$context.requestTime,$context.httpMethod,$context.resourcePath,$context.protocol,$context.status,$context.responseLength,$context.requestId,$context.extendedRequestId
  ```

## CloudWatch 로깅에 대한 권한
<a name="set-up-access-logging-permissions"></a>

CloudWatch Logs를 활성화하려면 계정의 CloudWatch에 로그를 읽고 쓸 수 있는 권한을 API Gateway에 부여해야 합니다. [AmazonAPIGatewayPushToCloudWatchLogs](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonAPIGatewayPushToCloudWatchLogs.html)에는 필요한 모든 권한이 있습니다.

**참고**  
API Gateway는 IAM 역할을 수임하기 위해 AWS Security Token Service를 호출하므로 AWS STS가 해당 리전에 대해 활성화되어 있는지 확인하십시오. 자세한 내용은 [AWS 리전에서 AWS STS 관리](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)를 참조하세요.

이러한 권한을 계정에 부여하려면 신뢰할 수 있는 엔터티로 `apigateway.amazonaws.com`이 포함된 IAM 역할을 생성하고, 이전 정책을 이 IAM 역할에 연결한 다음, [계정](https://docs.aws.amazon.com/apigateway/latest/api/API_GetAccount.html)의 [cloudWatchRoleArn](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateAccount.html#cloudWatchRoleArn) 속성에서 IAM 역할 ARN을 설정합니다. CloudWatch Logs를 활성화하려는 각 AWS 리전에 대해 개별적으로 [cloudWatchRoleArn](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateAccount.html#cloudWatchRoleArn) 속성을 설정해야 합니다.

IAM 역할 ARN을 설정할 때 오류가 발생하는 경우, AWS Security Token Service 계정 설정을 확인하여 사용 중인 리전에 AWS STS가 활성화되어 있는지 확인합니다. AWS STS 활성화에 대한 자세한 내용은 *IAM 사용 설명서*의 [AWS 리전에서 AWS STS 관리](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-activate-deactivate)를 참조하세요.

## API Gateway 콘솔을 사용하여 CloudWatch API 로깅 설정
<a name="set-up-access-logging-using-console"></a>

CloudWatch API 로깅을 설정하려면 API를 단계에 배포해야 합니다. 또한 계정에 대해 [적절한 CloudWatch Logs 역할](#set-up-access-logging-permissions) ARN도 구성해야 합니다.

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. 기본 탐색 창에서 **설정**을 선택한 다음 **로깅**에서 **편집**을 선택합니다.

1. **CloudWatch 로그 역할 ARN**에서 적절한 권한이 있는 IAM 역할의 ARN을 입력합니다. API Gateway를 사용하여 API를 생성하는 AWS 계정마다 이 작업을 한 번씩 수행해야 합니다.

1. 기본 탐색 창에서 **API**를 선택하고 다음 중 하나를 수행합니다.

   1.  기존 API를 선택한 다음 스테이지를 선택합니다.

   1.  API를 생성하여 스테이지에 배포합니다.

1. 기본 탐색 창에서 **스테이지**를 선택합니다.

1.  **로그 및 추적** 섹션에서 **편집**을 선택합니다.

1. 실행 로깅을 활성화하려면 다음과 같이 합니다.

   1. **CloudWatch Logs** 드롭다운 메뉴에서 로깅 수준을 선택합니다. 로깅 수준은 다음과 같습니다:
      + **끄기** - 이 단계에서는 로깅이 켜져 있지 않습니다.
      + **오류만** - 오류에 대해서만 로깅이 활성화됩니다.
      + **오류 및 정보 로그** - 모든 이벤트에 대해 로깅이 활성화됩니다.

   1. (선택 사항) **데이터 추적**을 선택하여 단계의 데이터 추적 로깅을 활성화합니다. 이 기능은 API 문제를 해결하는 데 유용하지만 민감한 데이터를 로깅할 수 있습니다.
**참고**  
프로덕션 API에는 **데이터 추적**을 사용하지 않는 것이 좋습니다.

   1. (선택 사항) **세부 지표**를 선택하여 CloudWatch 세부 지표를 활성화합니다.

   CloudWatch 지표에 대한 자세한 내용은 [Amazon CloudWatch 지표를 사용한 REST API 실행 모니터링](monitoring-cloudwatch.md) 단원을 참조하십시오.

1. 액세스 로깅을 활성화하려면 다음과 같이 합니다.

   1. **사용자 지정 액세스 로깅**을 활성화합니다.

   1. **액세스 로그 대상 ARN**에 로그 그룹의 ARN을 입력합니다. ARN 형식은 `arn:aws:logs:{region}:{account-id}:log-group:log-group-name`입니다.

   1. **로그 형식**에 로그 형식을 입력합니다. **CLF**, **JSON**, **XML** 또는 **CSV**를 선택할 수 있습니다. 예제 로그 형식에 대한 자세한 내용은 [API Gateway에 대한 CloudWatch 로그 형식](#apigateway-cloudwatch-log-formats) 섹션을 참조하세요.

1. **변경 사항 저장**을 선택합니다.

**참고**  
실행 로깅과 액세스 로깅을 서로 독립적으로 활성화할 수 있습니다.

이제 API Gateway가 API에 대한 요청을 로깅할 준비가 되었습니다. 단계 설정, 로그 또는 단계 변수를 업데이트할 때 API를 다시 배포할 필요가 없습니다.

## CloudFormation을 사용하여 CloudWatch API 로깅 설정
<a name="set-up-access-logging-using-cloudformation"></a>

다음 예제 CloudFormation 템플릿을 사용하여 Amazon CloudWatch Logs 로그 그룹을 생성하고 단계에 대한 실행 및 액세스 로깅을 구성합니다. CloudWatch Logs를 활성화하려면 계정의 CloudWatch에 로그를 읽고 쓸 수 있는 권한을 API Gateway에 부여해야 합니다. 자세한 내용은 *AWS CloudFormation 사용 설명서*의 [계정과 IAM 역할 연결](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-account.html#aws-resource-apigateway-account--examples)을 참조하세요.

```
  TestStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      StageName: test
      RestApiId: !Ref MyAPI
      DeploymentId: !Ref Deployment
      Description: "test stage description"
      MethodSettings:
        - ResourcePath: "/*"
          HttpMethod: "*"
          LoggingLevel: INFO
      AccessLogSetting:
        DestinationArn: !GetAtt MyLogGroup.Arn
        Format: $context.extendedRequestId $context.identity.sourceIp $context.identity.caller $context.identity.user [$context.requestTime] "$context.httpMethod $context.resourcePath $context.protocol" $context.status $context.responseLength $context.requestId
  MyLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Join
        - '-'
        - - !Ref MyAPI
          - access-logs
```