

# 데이터베이스 활동 스트림을 사용하여 Amazon RDS 모니터링
<a name="DBActivityStreams"></a><a name="das"></a>

데이터베이스 활동 스트림을 사용하면 데이터베이스 활동 스트림을 거의 실시간으로 모니터링할 수 있습니다.

**Topics**
+ [데이터베이스 활동 스트림 개요](#DBActivityStreams.Overview)
+ [Oracle 데이터베이스 통합 감사 구성](DBActivityStreams.configuring-auditing.md)
+ [Amazon RDS for Microsoft SQL Server에 대한 감사 정책 구성](DBActivityStreams.configuring-auditing-SQLServer.md)
+ [데이터베이스 활동 스트림 시작](DBActivityStreams.Enabling.md)
+ [Amazon RDS에 대한 데이터베이스 활동 스트림 수정](DBActivityStreams.Modifying.md)
+ [데이터베이스 활동 스트림 상태 가져오기](DBActivityStreams.Status.md)
+ [데이터베이스 활동 스트림 중지](DBActivityStreams.Disabling.md)
+ [데이터베이스 활동 스트림 모니터링](DBActivityStreams.Monitoring.md)
+ [데이터베이스 활동 스트림의 IAM 정책 예제](DBActivityStreams.ManagingAccess.md)

## 데이터베이스 활동 스트림 개요
<a name="DBActivityStreams.Overview"></a>

Amazon RDS 데이터베이스 관리자는 데이터베이스를 보호하고 규정 준수 및 규제 요건을 충족해야 합니다. 한 가지 전략은 데이터베이스 활동 스트림을 모니터링 도구와 통합하는 것입니다. 이렇게 하면 데이터베이스에서 감사 활동에 대한 경보를 모니터링하고 설정할 수 있습니다.

보안 위협은 외부 및 내부 위협입니다. 내부 위협으로부터 보호하기 위해 데이터베이스 활동 스트림 기능을 구성하여 데이터 스트림에 대한 관리자 액세스를 제어할 수 있습니다. Amzon RDS DBA는 스트림의 수집, 전송, 저장 및 처리에 대한 액세스 권한이 없습니다.

**Contents**
+ [데이터베이스 활동 스트림 작동 방식](#DBActivityStreams.Overview.how-they-work)
+ [Oracle 데이터베이스 및 SQL Server 데이터베이스에서의 감사](#DBActivityStreams.Overview.auditing)
  + [Oracle 데이터베이스의 통합 감사](#DBActivityStreams.Overview.unified-auditing)
  + [Microsoft SQL Server에서의 감사](#DBActivityStreams.Overview.SQLServer-auditing)
  + [Oracle Database 및 SQL Server에 대한 기본이 아닌 감사 필드](#DBActivityStreams.Overview.unified-auditing.non-native)
  + [DB 파라미터 그룹 재정의](#DBActivityStreams.Overview.unified-auditing.parameter-group)
+ [데이터베이스 활동 스트림에 대한 비동기식 모드](#DBActivityStreams.Overview.sync-mode)
+ [데이터베이스 활동 스트림의 요구 사항 및 제한 사항](#DBActivityStreams.Overview.requirements)
+ [리전 및 버전 사용 가능 여부](#DBActivityStreams.RegionVersionAvailability)
+ [데이터베이스 활동 스트림이 지원되는 DB 인스턴스 클래스](#DBActivityStreams.Overview.requirements.classes)

### 데이터베이스 활동 스트림 작동 방식
<a name="DBActivityStreams.Overview.how-they-work"></a>

Amazon RDS는 활동을 Amazon Kinesis 데이터 스트림에 거의 실시간으로 푸시합니다. Kinesis 스트림이 자동으로 생성됩니다. Kinesis에서 Amazon Data Firehose 및 AWS Lambda와 같은 AWS 서비스를 구성하여 스트림을 사용하고 데이터를 저장할 수 있습니다.

**중요**  
Amazon RDS에서 데이터베이스 활동 스트림은 무료 기능이지만, Amazon Kinesis는 데이터 스트림에 대한 요금을 부과합니다. 자세한 내용은 [Amazon Kinesis Data Streams 요금](https://aws.amazon.com/kinesis/data-streams/pricing/)을 참조하세요.

규정 준수 관리용 애플리케이션이 데이터베이스 활동 스트림을 사용하도록 구성할 수 있습니다. 이 애플리케이션은 스트림을 사용하여  데이터베이스에 대한 경보를 생성하고 활동 감사를 수행할 수 있습니다.

Amazon RDS는 다중 AZ 배포에서 데이터베이스 활동 스트림을 지원합니다. 이 경우 데이터베이스 활동 스트림은 기본 인스턴스와 대기 인스턴스를 모두 감사합니다.

### Oracle 데이터베이스 및 SQL Server 데이터베이스에서의 감사
<a name="DBActivityStreams.Overview.auditing"></a>

감사는 구성된 데이터베이스 작업의 모니터링 및 기록입니다. Amazon RDS는 기본적으로 데이터베이스 활동을 캡처하지 않습니다. 사용자가 데이터베이스에서 직접 감사 정책을 생성하고 관리합니다.

**Topics**
+ [Oracle 데이터베이스의 통합 감사](#DBActivityStreams.Overview.unified-auditing)
+ [Microsoft SQL Server에서의 감사](#DBActivityStreams.Overview.SQLServer-auditing)
+ [Oracle Database 및 SQL Server에 대한 기본이 아닌 감사 필드](#DBActivityStreams.Overview.unified-auditing.non-native)
+ [DB 파라미터 그룹 재정의](#DBActivityStreams.Overview.unified-auditing.parameter-group)

#### Oracle 데이터베이스의 통합 감사
<a name="DBActivityStreams.Overview.unified-auditing"></a>

Oracle 데이터베이스에서 *통합 감사 정책*은 사용자 동작의 측면을 감사하는 데 사용할 수 있는 명명된 감사 설정 그룹입니다. 정책은 단일 사용자의 활동을 감사하는 것만큼 간단할 수 있습니다. 또한 조건을 사용하는 복잡한 감사 정책을 생성할 수도 있습니다.

Oracle 데이터베이스는 `SYS` 감사 레코드를 포함한 감사 레코드를 *통합 감사 추적*에 기록합니다. 예를 들어, `INSERT` 문 중에 오류가 발생하는 경우 표준 감사는 오류 번호와 실행된 SQL을 보여줍니다. 감사 추적은 `AUDSYS` 스키마에 있는 읽기 전용 테이블에 상주합니다. `UNIFIED_AUDIT_TRAIL` 데이터 사전 보기를 쿼리하여 이러한 레코드에 액세스합니다.

일반적으로 데이터베이스 활동 스트림을 다음과 같이 구성합니다.

1. `CREATE AUDIT POLICY` 명령을 사용하여 Oracle 데이터베이스 감사 정책을 생성합니다.

   Oracle 데이터베이스는 감사 레코드를 생성합니다.

1. `AUDIT POLICY` 명령을 사용하여 감사 정책을 활성화합니다.

1. 데이터베이스 활동 스트림을 구성합니다.

   Oracle 데이터베이스 감사 정책과 일치하 는 활동만 캡처되어 Amazon Kinesis 데이터 스트림으로 전송됩니다. 데이터베이스 활동 스트림이 활성화된 경우 Oracle 데이터베이스 관리자는 감사 정책을 변경하거나 감사 로그를 제거할 수 없습니다.

통합 감사 정책에 대해 자세히 알아보려면 *Oracle Database Security Guide*에서 [About Auditing Activities with Unified Audit Policies and AUDIT](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/configuring-audit-policies.html#GUID-2435D929-10AD-43C7-8A6C-5133170074D0)를 참조하세요.

#### Microsoft SQL Server에서의 감사
<a name="DBActivityStreams.Overview.SQLServer-auditing"></a>

데이터베이스 활동 스트림은 SQLAudit 기능을 사용하여 SQL Server 데이터베이스를 감사합니다.

RDS for SQL Server 인스턴스에는 다음이 포함되어 있습니다.
+ 서버 감사 - SQL Server 감사는 서버 또는 데이터베이스 수준 작업의 단일 인스턴스와 모니터링할 작업 그룹을 수집합니다. 서버 수준 감사인 `RDS_DAS_AUDIT` 및 `RDS_DAS_AUDIT_CHANGES`는 RDS에서 관리합니다.
+ 서버 감사 사양 - 서버 감사 사양은 서버 수준 이벤트를 기록합니다. `RDS_DAS_SERVER_AUDIT_SPEC` 사양을 수정할 수 있습니다. 이 사양은 서버 감사 `RDS_DAS_AUDIT`과 연결되어 있습니다. `RDS_DAS_CHANGES_AUDIT_SPEC` 사양은 RDS에서 관리합니다.
+ 데이터베이스 감사 사양 - 데이터베이스 감사 사양은 데이터베이스 수준 이벤트를 기록합니다. 데이터베이스 감사 사양 `RDS_DAS_DB_<name>`을 생성하여 `RDS_DAS_AUDIT` 서버 감사에 연결할 수 있습니다.

콘솔 또는 CLI를 사용하여 데이터베이스 활동 스트림을 구성할 수 있습니다. 일반적으로 데이터베이스 활동 스트림을 다음과 같이 구성합니다.

1. (선택 사항) `CREATE DATABASE AUDIT SPECIFICATION` 명령을 사용하여 데이터베이스 감사 사양을 생성하고 이를 `RDS_DAS_AUDIT` 서버 감사에 연결합니다.

1. (선택 사항) `ALTER SERVER AUDIT SPECIFICATION` 명령을 사용하여 서버 감사 사양을 수정하고 정책을 정의합니다.

1. 데이터베이스 및 서버 감사 정책을 활성화합니다. 예제:

   `ALTER DATABASE AUDIT SPECIFICATION [<Your database specification>] WITH (STATE=ON)`

   `ALTER SERVER AUDIT SPECIFICATION [RDS_DAS_SERVER_AUDIT_SPEC] WITH (STATE=ON)`

1. 데이터베이스 활동 스트림을 구성합니다.

   서버 및 데이터베이스 감사 정책과 일치하는 활동만 캡처되어 Amazon Kinesis 데이터 스트림으로 전송됩니다. 데이터베이스 활동 스트림이 활성화되고 정책이 잠겨 있는 경우 데이터베이스 관리자는 감사 정책을 변경하거나 감사 로그를 제거할 수 없습니다.
**중요**  
특정 데이터베이스에 대한 데이터베이스 감사 사양이 활성화되어 있고 정책이 잠긴 상태이면 데이터베이스를 삭제할 수 없습니다.

SQL Server 감사에 자세한 내용은 **Microsoft SQL Server 설명서의 [SQL Server Audit 구성 요소](https://learn.microsoft.com/en-us/sql/relational-databases/security/auditing/sql-server-audit-database-engine?view=sql-server-ver16)를 참조하세요.



#### Oracle Database 및 SQL Server에 대한 기본이 아닌 감사 필드
<a name="DBActivityStreams.Overview.unified-auditing.non-native"></a>

데이터베이스 활동 스트림을 시작하면 모든 데이터베이스 이벤트는 해당하는 활동 스트림 이벤트를 생성합니다. 예를 들어 데이터베이스 사용자는 `SELECT` 및 `INSERT` 문을 실행합니다. 데이터베이스는 이러한 이벤트를 감사하여 Amazon Kinesis 데이터 스트림으로 전송합니다.

이 이벤트는 스트림에서 JSON 객체로 표현됩니다. JSON 객체는 `databaseActivityEventList` 배열이 있는 `DatabaseActivityMonitoringRecord`를 포함합니다. 배열의 미리 정의된 필드는 `class`, `clientApplication` 및 `command`를 포함합니다.

기본적으로 활동 스트림은 엔진 기본 감사 필드를 포함하지 않습니다. `engineNativeAuditFields` JSON 객체에 이러한 추가 필드가 포함되도록 Amazon RDS for Oracle 및 SQL Server를 구성할 수 있습니다.

Oracle Database에서 통합 감사 추적의 대부분 이벤트는 RDS 데이터 활동 스트림의 필드에 매핑됩니다. 예를 들어, 통합 감사의 `UNIFIED_AUDIT_TRAIL.SQL_TEXT` 필드는 데이터베이스 활동 스트림의 `commandText` 필드에 매핑됩니다. 그러나 `OS_USERNAME`과 같은 Oracle 데이터베이스 감사 필드는 데이터베이스 활동 스트림에 있는 미리 정의된 필드에 매핑되지 않습니다.

SQL Server에서 SQLAudit에 의해 기록되는 대부분의 이벤트 필드는 RDS 데이터베이스 활동 스트림의 필드에 매핑됩니다. 예를 들어, 통합 감사의 `sys.fn_get_audit_file`에 있는 `code` 필드는 데이터베이스 활동 스트림의 `commandText` 필드에 매핑됩니다. 그러나 `permission_bitmask`와 같은 SQL Server 데이터베이스 감사 필드는 데이터베이스 활동 스트림에 있는 미리 정의된 필드에 매핑되지 않습니다.

databaseActivityEventList에 대한 자세한 내용은 [데이터베이스 활동 스트림에 대한 databaseActivityEventList JSON 배열](DBActivityStreams.AuditLog.databaseActivityEventList.md) 섹션을 참조하세요.

#### DB 파라미터 그룹 재정의
<a name="DBActivityStreams.Overview.unified-auditing.parameter-group"></a>

일반적으로 파라미터 그룹을 연결하여 RDS for Oracle에서 통합 감사를 활성화합니다. 그러나 데이터베이스 활동 스트림에는 추가 구성이 필요합니다. 고객 경험을 개선하기 위해 Amazon RDS는 다음을 수행합니다.
+ 활동 스트림을 활성화하면 RDS for Oracle은 파라미터 그룹의 감사 파라미터를 무시합니다.
+ 활동 스트림을 비활성화하면 RDS for Oracle은 감사 파라미터 무시를 중단합니다.

SQL Server에 대한 데이터베이스 활동 스트림은 SQL Audit 옵션에서 설정한 파라미터와는 독립적입니다.

### 데이터베이스 활동 스트림에 대한 비동기식 모드
<a name="DBActivityStreams.Overview.sync-mode"></a>

Amazon RDS의 활동 스트림은 항상 비동기식입니다. 데이터베이스 세션이 활동 스트림 이벤트를 생성하면 세션은 즉시 정상 활동으로 되돌아갑니다. Amazon RDS는 백그라운드에서 내구성 있는 레코드에 활동 스트림 이벤트를 생성합니다.

백그라운드 태스크에서 오류가 발생하면 Amazon RDS가 이벤트를 생성합니다. 이 이벤트는 활동 스트림 이벤트 레코드가 분실되었을 수있는 기간의 시작과 끝을 나타냅니다. 비동기 모드는 활동 스트림의 정확성보다 데이터베이스 성능을 우선시합니다.

### 데이터베이스 활동 스트림의 요구 사항 및 제한 사항
<a name="DBActivityStreams.Overview.requirements"></a>

RDS에서 데이터베이스 활동 스트림에는 다음과 같은 요구 사항과 제한 사항이 있습니다.
+ 데이터베이스 활동 스트림에는 Amazon Kinesis를 사용해야 합니다.
+ 데이터베이스 활동 스트림은 항상 암호화되므로 AWS Key Management Service(AWS KMS)를 사용해야 합니다.
+ Amazon Kinesis 데이터 스트림에 추가 암호화를 적용하는 것은 이미 AWS KMS 키를 사용하여 암호화된 데이터베이스 활동 스트림과 호환되지 않습니다.
+ 사용자가 직접 감사 정책을 생성하고 관리합니다. Amazon Aurora와 달리 RDS for Oracle은 기본적으로 데이터베이스 활동을 캡처하지 않습니다.
+ 사용자가 직접 감사 정책 또는 사양을 생성하고 관리합니다. Amazon Aurora와 달리 Amazon RDS는 기본적으로 데이터베이스 활동을 캡처하지 않습니다.
+ 다중 AZ 배포에서 기본 DB 인스턴스에서만 데이터베이스 활동 스트림을 시작합니다. 활동 스트림은 기본 DB 인스턴스와 대기 DB 인스턴스를 모두 자동으로 감사합니다. 장애 조치 중에는 추가 단계가 필요 없습니다.
+ DB 인스턴스의 이름을 변경해도 새 Kinesis 스트림이 생성되지는 않습니다.
+ CDB는 RDS for Oracle에 대해 지원되지 않습니다.
+ 읽기 전용 복제본은 지원되지 않습니다.

### 리전 및 버전 사용 가능 여부
<a name="DBActivityStreams.RegionVersionAvailability"></a>

기능 가용성 및 해당 지원은 각 데이터베이스 엔진의 특정 버전 및 AWS 리전마다 다릅니다. 데이터베이스 활동 스트림의 버전 및 지역 가용성에 대한 자세한 내용은 [Amazon RDS에서 데이터베이스 활동 스트림을 지원하는 리전 및 DB 엔진](Concepts.RDS_Fea_Regions_DB-eng.Feature.DBActivityStreams.md) 단원을 참조하세요.

### 데이터베이스 활동 스트림이 지원되는 DB 인스턴스 클래스
<a name="DBActivityStreams.Overview.requirements.classes"></a>

RDS for Oracle의 경우 다음 DB 인스턴스 클래스와 함께 데이터베이스 활동 스트림을 사용할 수 있습니다.
+ db.m4.\$1large
+ db.m5.\$1large
+ db.m5d.\$1large
+ db.m6i.\$1large
+ db.r4.\$1large
+ db.r5.\$1large
+ db.r5.\$1large.tpc\$1.mem\$1x
+ db.r5b.\$1large
+ db.r5b.\$1large.tpc\$1.mem\$1x
+ db.r5d.\$1large
+ db.r6i.\$1large
+ db.r6i.\$1large.tpc\$1.mem\$1x
+ db.x2idn.\$1large
+ db.x2iedn.\$1large
+ db.x2iezn.\$1large
+ db.z1d.\$1large

RDS for sQL Server의 경우 다음 DB 인스턴스 클래스와 함께 데이터베이스 활동 스트림을 사용할 수 있습니다.
+ db.m4.\$1large
+ db.m5.\$1large
+ db.m5d.\$1large
+ db.m6i.\$1large
+ db.r4.\$1large
+ db.r5.\$1large
+ db.r5b.\$1large
+ db.r5d.\$1large
+ db.r6i.\$1large
+ db.x1e.\$1large
+ db.x2iedn.\$1large
+ db.z1d.\$1large

인스턴스 클래스 유형에 대한 자세한 내용은 [DB 인스턴스 클래스](Concepts.DBInstanceClass.md) 섹션을 참조하세요.

# Oracle 데이터베이스 통합 감사 구성
<a name="DBActivityStreams.configuring-auditing"></a>

데이터베이스 활동 스트림에 사용할 통합 감사를 구성하는 경우 다음과 같은 상황이 발생할 수 있습니다.
+ Oracle 데이터베이스에 통합 감사가 구성되지 않았습니다.

  이 경우 `CREATE AUDIT POLICY` 명령을 사용하여 새 정책을 생성하고 `AUDIT POLICY` 명령을 사용하여 정책을 활성화합니다. 다음 예시에서는 특정 권한 및 역할을 가진 사용자를 모니터링하는 정책을 만들고 활성화합니다.

  ```
  CREATE AUDIT POLICY table_pol
  PRIVILEGES CREATE ANY TABLE, DROP ANY TABLE
  ROLES emp_admin, sales_admin;
  
  AUDIT POLICY table_pol;
  ```

  전체 지침은 Oracle 데이터베이스 문서에서 [Configuring Audit Policies](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/configuring-audit-policies.html#GUID-22CDB667-5AA2-4051-A262-FBD0236763CB)를 참조하세요.
+ 통합 감사는 Oracle 데이터베이스에 대해 구성됩니다.

  데이터베이스 활동 스트림을 활성화하면 RDS for Oracle에서 기존 감사 데이터를 자동으로 지웁니다. 또한 감사 추적 권한도 취소됩니다. RDS for Oracle은 더 이상 다음을 수행하지 않습니다.
  + 통합 감사 추적 레코드 삭제
  + 통합 감사 정책 추가, 삭제 또는 수정
  + 마지막으로 아카이빙된 타임스탬프 업데이트
**중요**  
데이터베이스 활동 스트림을 활성화하기 전에 감사 데이터를 백업하는 것이 좋습니다.

  `UNIFIED_AUDIT_TRAIL` 보기에 대한 설명은 [UNIFIED\$1AUDIT\$1TRAIL](https://docs.oracle.com/database/121/REFRN/GUID-B7CE1C02-2FD4-47D6-80AA-CF74A60CDD1D.htm#REFRN29162)을 참조하세요. Oracle Support 계정이 있는 경우 [How To Purge The UNIFIED AUDIT TRAIL](https://support.oracle.com/knowledge/Oracle%20Database%20Products/1582627_1.html)을 참조하세요.

# Amazon RDS for Microsoft SQL Server에 대한 감사 정책 구성
<a name="DBActivityStreams.configuring-auditing-SQLServer"></a>

SQL Server 데이터베이스 인스턴스에는 Amazon RDS에서 관리하는 서버 감사(`RDS_DAS_AUDIT`)가 있습니다. 정책을 정의하여 서버 감사 사양(`RDS_DAS_SERVER_AUDIT_SPEC`)에 서버 이벤트를 기록할 수 있습니다. 데이터베이스 감사 사양(예: `RDS_DAS_DB_<name>`)을 생성하고 데이터베이스 이벤트를 기록하는 정책을 정의할 수 있습니다. 서버 및 데이터베이스 수준 감사 작업 그룹 목록은 **Microsoft SQL Server 설명서의 [SQL Server 감사 작업 그룹 및 작업](https://learn.microsoft.com/en-us/sql/relational-databases/security/auditing/sql-server-audit-action-groups-and-actions)을 참조하세요.

기본 서버 정책은 실패한 로그인과 데이터베이스 활동 스트림에 대한 데이터베이스 또는 서버 감사 사양의 변경만 모니터링합니다.

감사 및 감사 사양에 대한 제한 사항은 다음과 같습니다.
+ 데이터베이스 활동 스트림이 **잠긴 상태일 때는 서버 또는 데이터베이스 감사 사양을 수정할 수 없습니다.
+ 서버 감사 `RDS_DAS_AUDIT` 사양을 수정할 수 없습니다.
+ SQL Server 감사 `RDS_DAS_CHANGES` 또는 관련 서버 감사 사양 `RDS_DAS_CHANGES_AUDIT_SPEC`을 수정할 수 없습니다.
+ 데이터베이스 감사 사양을 만들 때는 `RDS_DAS_DB_<name>` 형식(예: `RDS_DAS_DB_databaseActions`)을 사용해야 합니다.

**중요**  
소규모 인스턴스 클래스의 경우 모든 데이터를 감사하지 않고 필요한 데이터만 감사하는 것이 좋습니다. 이렇게 하면 데이터베이스 활동 스트림이 이러한 인스턴스 클래스 성능에 미치는 영향을 줄일 수 있습니다.

다음 샘플 코드는 서버 감사 사양 `RDS_DAS_SERVER_AUDIT_SPEC`을 수정하고 로그아웃 및 성공적인 로그인 작업을 감사합니다.

```
ALTER SERVER AUDIT SPECIFICATION [RDS_DAS_SERVER_AUDIT_SPEC]
      WITH (STATE=OFF);
ALTER SERVER AUDIT SPECIFICATION [RDS_DAS_SERVER_AUDIT_SPEC]
      ADD (LOGOUT_GROUP),
      ADD (SUCCESSFUL_LOGIN_GROUP)
      WITH (STATE = ON );
```

다음 샘플 코드는 데이터베이스 감사 사양 `RDS_DAS_DB_database_spec`을 생성하여 서버 감사 `RDS_DAS_AUDIT`에 첨부합니다.

```
USE testDB;
CREATE DATABASE AUDIT SPECIFICATION [RDS_DAS_DB_database_spec]
     FOR SERVER AUDIT [RDS_DAS_AUDIT]
     ADD ( INSERT, UPDATE, DELETE  
          ON testTable BY testUser )  
     WITH (STATE = ON);
```

감사 사양을 구성한 후에는 사양 `RDS_DAS_SERVER_AUDIT_SPEC` 및 `RDS_DAS_DB_<name>`의 상태가 `ON`으로 설정되어 있는지 확인합니다. 이제 해당 사양이 감사 데이터를 데이터베이스 활동 스트림으로 보낼 수 있습니다.

# 데이터베이스 활동 스트림 시작
<a name="DBActivityStreams.Enabling"></a>

DB 인스턴스 에 대해 활동 스트림을 시작하면 감사 정책에 구성한 각 데이터베이스 활동 이벤트가 활동 스트림 이벤트를 생성합니다. `CONNECT` 및 `SELECT` 같은 SQL 명령은 액세스 이벤트를 생성합니다. `CREATE` 및 `INSERT` 같은 SQL 명령은 변경 이벤트를 생성합니다.

**중요**  
Oracle DB 인스턴스에 대해 활동 스트림을 활성화하면 기존 감사 데이터를 지웁니다. 또한 감사 추적 권한도 취소됩니다. 스트림이 활성화된 경우 RDS for Oracle은 더 이상 다음 작업을 수행할 수 없습니다.  
통합 감사 추적 레코드 삭제
통합 감사 정책 추가, 삭제 또는 수정
마지막으로 아카이빙된 타임스탬프 업데이트

------
#### [ Console ]

**데이터베이스 활동 스트림을 시작하려면**

1. [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)에서 Amazon RDS 콘솔을 엽니다.

1. 탐색 창에서 **데이터베이스**를 선택합니다.

1. 활동 스트림을 시작하려는 Amazon RDS 데이터베이스 인스턴스를 선택합니다. 다중 AZ 배포에서 기본 인스턴스에서만 스트림을 시작합니다. 활동 스트림은 기본 및 대기 DB 인스턴스를 모두 감사합니다.

1. **작업**의 경우 **Start activity stream(활동 스트림 시작)**을 선택합니다.

   **데이터베이스 활동 스트림 시작: ***이름* 창이 나타납니다. 여기서 *이름*은 사용자의 RDS 인스턴스입니다.

1. 다음 설정을 입력합니다.
   + **AWS KMS key**의 경우, AWS KMS keys 목록에서 키를 선택합니다.

     RDS for Oracle이 KMS 키를 사용하여 키를 암호화하면 암호화된 키가 데이터베이스 활동을 암호화합니다. 기본 키가 아닌 KMS 키를 선택합니다. 암호화 키 및 AWS KMS에 대한 자세한 내용은 *AWS Key Management Service 개발자 안내서에서 *[AWS Key Management Service란 무엇입니까?](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html)를 참조하세요.
   + **데이터베이스 활동 이벤트**에서 **엔진 고유 감사 필드 활성화**를 선택하여 엔진 고유의 감사 필드를 포함합니다.
   + [**즉시(Immediately))**를 선택합니다.

     [**즉시(Immediately)**]를 선택하면 RDS 인스턴스가 바로 다시 시작됩니다. [**다음 유지 관리 기간 중(During the next maintenance window)**]을 선택하면 RDS 인스턴스는 즉시 다시 시작되지 않습니다. 이 경우 데이터베이스 활동 스트림은 다음 유지 관리 기간까지 시작되지 않습니다.

1. **데이터베이스 활동 스트림 시작**을 선택합니다.

   데이터베이스에 대한 상태는 활동 스트림이 시작 중임을 보여줍니다.
**참고**  
`You can't start a database activity stream in this configuration` 오류가 발생하는 경우 RDS 인스턴스가 지원되는 인스턴스 클래스를 사용하고 있는지 [데이터베이스 활동 스트림이 지원되는 DB 인스턴스 클래스](DBActivityStreams.md#DBActivityStreams.Overview.requirements.classes)에서 확인하세요.

------
#### [ AWS CLI ]

DB 인스턴스에 대해 데이터베이스 활동 스트림을 시작하려면 [start-activity-stream](https://docs.aws.amazon.com/cli/latest/reference/rds/start-activity-stream.html) AWS CLI 명령을 사용하여 데이터베이스를 구성합니다.
+ `--resource-arn arn` - DB 인스턴스의 Amazon 리소스 이름(ARN)을 지정합니다.
+ `--kms-key-id key` - 데이터베이스 활동 스트림에서 메시지를 암호화하기 위한 KMS 키 식별자를 지정합니다. AWS KMS 키 식별자는 AWS KMS key의 키 ARN, 키 ID, 별칭 ARN 또는 별칭 이름입니다.
+ `--engine-native-audit-fields-included` - 데이터 스트림에 엔진별 감사 필드를 포함합니다. 이러한 필드를 제외하려면 `--no-engine-native-audit-fields-included`(default)을 지정합니다.

다음 예에서는 비동기 모드에서 DB 인스턴스에 대한 데이터베이스 활동 스트림을 시작합니다.

대상 LinuxmacOS, 또는Unix:

```
aws rds start-activity-stream \
    --mode async \
    --kms-key-id my-kms-key-arn \
    --resource-arn my-instance-arn \
    --engine-native-audit-fields-included \
    --apply-immediately
```

Windows의 경우:

```
aws rds start-activity-stream ^
    --mode async ^
    --kms-key-id my-kms-key-arn ^
    --resource-arn my-instance-arn ^
    --engine-native-audit-fields-included ^
    --apply-immediately
```

------
#### [ Amazon RDS API ]

DB 인스턴스에 대해 데이터베이스 활동 스트림을 시작하려면 [StartActivityStream](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_StartActivityStream.html) 작업을 사용하여 인스턴스를 구성합니다.

아래 파라미터를 사용하여 작업을 호출하세요.
+ `Region`
+ `KmsKeyId`
+ `ResourceArn`
+ `Mode`
+ `EngineNativeAuditFieldsIncluded`

------

# Amazon RDS에 대한 데이터베이스 활동 스트림 수정
<a name="DBActivityStreams.Modifying"></a>

활동 스트림이 시작될 때 Amazon RDS 감사 정책을 사용자 지정하는 것이 좋습니다. 활동 스트림을 중지하여 시간과 데이터를 잃지 않으려면 *감사 정책 상태*를 다음 설정 중 하나로 변경할 수 있습니다.

**잠김(기본값)**  
데이터베이스의 감사 정책은 읽기 전용입니다.

**잠금 해제됨**  
데이터베이스의 감사 정책은 읽기/쓰기가 가능합니다.

기본 단계는 다음과 같습니다.

1. 감사 정책 상태를 잠금 해제된 상태로 수정합니다.

1. 감사 정책을 사용자 정의합니다.

1. 감사 정책 상태를 잠김 상태로 수정합니다.

## 콘솔
<a name="DBActivityStreams.Modifying-collapsible-section-E1"></a>

**활동 스트림의 감사 정책 상태를 수정하려면**

1. [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)에서 Amazon RDS 콘솔을 엽니다.

1. 탐색 창에서 **데이터베이스**를 선택합니다.

1. **작업**에서는 **데이터베이스 활동 스트림 수정**을 선택합니다.

   **데이터베이스 활동 스트림 시작: *name*** 창이 나타납니다. 여기서 *name*은 사용자의 RDS 인스턴스입니다.

1. 다음 옵션 중 하나를 선택합니다.  
**잠김**  
감사 정책을 잠그면 읽기 전용으로 바뀝니다. 정책을 잠금 해제하거나 활동 스트림을 중지하지 않는 한 감사 정책을 편집할 수 없습니다.  
**잠금 해제됨**  
감사 정책을 잠금 해제하면 읽기/쓰기가 가능합니다. 활동 스트림이 시작되는 동안 감사 정책을 편집할 수 있습니다.

1. **DB 활동 스트림 수정**을 선택합니다.

   Amazon RDS 데이터베이스에 대한 상태는 **활동 스트림이 구성 중**임을 보여줍니다.

1. (선택 사항) DB 인스턴스 링크를 선택합니다. 그런 다음 **구성** 탭을 선택합니다.

   이 **감사 정책 상태** 필드는 다음 값 중 하나를 표시합니다.
   + **잠김**
   + **잠금 해제됨**
   + **잠금 정책**
   + **잠금 해제 정책**

## AWS CLI
<a name="DBActivityStreams.Modifying-collapsible-section-E2"></a>

데이터베이스 인스턴스의 활동 스트림 상태를 수정하려면 [modify-activity-stream](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-activity-stream.html) AWS CLI 명령을 사용하세요.


****  

| 옵션 | 필수? | Description | 
| --- | --- | --- | 
|  `--resource-arn my-instance-ARN`  |  예  |  RDS 데이터베이스 인스턴스의 Amazon 리소스 이름(ARN)입니다.  | 
|  `--audit-policy-state`  |  아니요  |  인스턴스의 데이터베이스 활동 스트림에 대한 감사 정책의 새 상태는 `locked` 또는 `unlocked`입니다.  | 

다음 예는 *my-instance-ARN*에서 시작된 활동 스트림에 대한 감사 정책을 잠금 해제합니다.

대상 LinuxmacOS, 또는Unix:

```
aws rds modify-activity-stream \
    --resource-arn my-instance-ARN \
    --audit-policy-state unlocked
```

Windows의 경우:

```
aws rds modify-activity-stream ^
    --resource-arn my-instance-ARN ^
    --audit-policy-state unlocked
```

다음 예에서는 *my-instance* 인스턴스를 설명합니다. 부분 샘플 출력은 감사 정책이 잠금 해제되었음을 보여줍니다.

```
aws rds describe-db-instances --db-instance-identifier my-instance

{
    "DBInstances": [
        {
            ...
            "Engine": "oracle-ee",
            ...
            "ActivityStreamStatus": "started",
            "ActivityStreamKmsKeyId": "ab12345e-1111-2bc3-12a3-ab1cd12345e",
            "ActivityStreamKinesisStreamName": "aws-rds-das-db-AB1CDEFG23GHIJK4LMNOPQRST",
            "ActivityStreamMode": "async",
            "ActivityStreamEngineNativeAuditFieldsIncluded": true, 
            "ActivityStreamPolicyStatus": "unlocked",
            ...
        }
    ]
}
```

## RDS API
<a name="DBActivityStreams.Modifying-collapsible-section-E3"></a>

데이터베이스 활동 스트림의 정책 상태를 수정하려면 [ModifyActivityStream](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyActivityStream.html) 작업을 사용합니다.

아래 파라미터를 사용하여 작업을 호출하세요.
+ `AuditPolicyState`
+ `ResourceArn`

# 데이터베이스 활동 스트림 상태 가져오기
<a name="DBActivityStreams.Status"></a>

콘솔 또는 AWS CLI를 사용하여 Amazon RDS 데이터베이스 인스턴스에 대한 활동 스트림의 상태를 가져올 수 있습니다.

## 콘솔
<a name="DBActivityStreams.Status-collapsible-section-S1"></a>

**데이터베이스 활동 스트림 상태 가져오기**

1. [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)에서 Amazon RDS 콘솔을 엽니다.

1. 탐색 창에서 [**데이터베이스(Databases)**]를 선택하고 DB 인스턴스 링크를 선택합니다.

1. **구성** 탭을 선택하고 **Database activity stream(데이터베이스 활동 스트림)**에서 상태를 확인하십시오.

## AWS CLI
<a name="DBActivityStreams.Status-collapsible-section-S2"></a>

 [describe-db-instances](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) CLI 요청에 대한 응답으로 데이터베이스 인스턴스에 대한 활동 스트림 구성을 가져올 수 있습니다.

다음 예는 *my-instance*를 설명합니다.

```
aws rds --region my-region describe-db-instances --db-instance-identifier my-db
```

다음 예에서는 JSON 응답을 보여 줍니다. 다음 필드가 표시됩니다.
+ `ActivityStreamKinesisStreamName`
+ `ActivityStreamKmsKeyId`
+ `ActivityStreamStatus`
+ `ActivityStreamMode`
+ `ActivityStreamPolicyStatus`



```
{
    "DBInstances": [
        {
            ...
            "Engine": "oracle-ee",
            ...
            "ActivityStreamStatus": "starting",
            "ActivityStreamKmsKeyId": "ab12345e-1111-2bc3-12a3-ab1cd12345e",
            "ActivityStreamKinesisStreamName": "aws-rds-das-db-AB1CDEFG23GHIJK4LMNOPQRST",
            "ActivityStreamMode": "async",
            "ActivityStreamEngineNativeAuditFieldsIncluded": true, 
            "ActivityStreamPolicyStatus": locked",
            ...
        }
    ]
}
```

## RDS API
<a name="DBActivityStreams.Status-collapsible-section-S3"></a>

 [DescribeDBInstances](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBInstances.html) 작업에 대한 응답으로 데이터베이스에 대한 활동 스트림 구성을 가져올 수 있습니다.

# 데이터베이스 활동 스트림 중지
<a name="DBActivityStreams.Disabling"></a>

콘솔 또는 AWS CLI를 사용하여 활동 스트림을 중지할 수 있습니다.

Amazon RDS 데이터베이스 인스턴스를 삭제하면 활동 스트림이 중지되고 기본 Amazon Kinesis 스트림이 자동으로 삭제됩니다.

## 콘솔
<a name="DBActivityStreams.Disabling-collapsible-section-D1"></a>

**활동 스트림을 끄려면**

1. [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)에서 Amazon RDS 콘솔을 엽니다.

1. 탐색 창에서 **데이터베이스**를 선택합니다.

1. 데이터베이스 활동 스트림을 중지하려는 데이터베이스를 선택하세요.

1. **작업**의 경우 **Stop activity stream(작업 스트림 중지)**을 선택합니다. **Database Activity Stream(데이터베이스 활동 스트림)** 창이 나타납니다.

   1. [**즉시(Immediately))**를 선택합니다.

      [**즉시(Immediately)**]를 선택하면 RDS 인스턴스가 바로 다시 시작됩니다. [**다음 유지 관리 기간 중(During the next maintenance window)**]을 선택하면 RDS 인스턴스는 즉시 다시 시작되지 않습니다. 이 경우 데이터베이스 활동 스트림은 다음 유지 관리 기간까지 중지되지 않습니다.

   1. [**Continue**]를 선택합니다.

## AWS CLI
<a name="DBActivityStreams.Disabling-collapsible-section-D2"></a>

데이터베이스에 대한 데이터베이스 활동 스트림을 중지하려면 AWS CLI 명령 [stop-activity-stream](https://docs.aws.amazon.com/cli/latest/reference/rds/stop-activity-stream.html)을 사용하여 DB 인스턴스를 구성하세요. `--region` 파라미터를 사용하여 DB 인스턴스에 대한 AWS 리전을 식별합니다. `--apply-immediately` 파라미터는 선택 항목입니다.

대상 LinuxmacOS, 또는Unix:

```
aws rds --region MY_REGION \
    stop-activity-stream \
    --resource-arn MY_DB_ARN \
    --apply-immediately
```

Windows의 경우:

```
aws rds --region MY_REGION ^
    stop-activity-stream ^
    --resource-arn MY_DB_ARN ^
    --apply-immediately
```

## RDS API
<a name="DBActivityStreams.Disabling-collapsible-section-D3"></a>

데이터베이스에 대해 데이터베이스 활동 스트림을 중지하려면 [StopActivityStream](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_StopActivityStream.html) 작업을 사용하여 DB 인스턴스를 구성합니다. `Region` 파라미터를 사용하여 DB 인스턴스에 대한 AWS 리전을 식별합니다. `ApplyImmediately` 파라미터는 선택 항목입니다.

# 데이터베이스 활동 스트림 모니터링
<a name="DBActivityStreams.Monitoring"></a>

데이터베이스 활동 스트림은 활동을 모니터링하고 보고합니다. 활동 스트림이 수집되어 Amazon Kinesis에 전송됩니다. Kinesis에서 활동 스트림을 모니터링하거나 다른 서비스 및 애플리케이션이 추가 분석을 위해 활동 스트림을 사용할 수 있습니다. AWS CLI 명령 `describe-db-instances` 또는 RDS API `DescribeDBInstances` 작업을 사용하여 기본 Kinesis 스트림 이름을 찾을 수 있습니다.

Amazon RDS는 다음과 같이 Kinesis 스트림을 관리합니다.
+ Amazon RDS는 24시간 보존 기간으로 Kinesis 스트림을 자동으로 생성합니다.
+  Amazon RDS는 필요한 경우 Kinesis 스트림 크기를 조정합니다.
+  데이터베이스 활동 스트림을 중지하거나 DB 인스턴스를 삭제하면 Amazon RDS에서 Kinesis 스트림을 삭제합니다.

다음 활동 범주가 모니터링되고 활동 스트림 감사 로그에 기록됩니다.
+ **SQL 명령** – 모든 SQL 명령이 감사되고 PL/SQL에서 준비된 문, 내장 함수 및 함수도 제공됩니다. 저장 프로시저에 대한 호출이 감사됩니다. 저장 프로시저 또는 함수 내에서 발급된 모든 SQL 문도 감사됩니다.
+ **다른 데이터베이스 정보** – 모니터링되는 활동에는 전체 SQL 문, DML 명령의 영향을 받은 행의 행 수, 액세스된 객체 및 고유한 데이터베이스 이름이 포함됩니다. 데이터베이스 활동 스트림은 바인딩 변수와 저장 프로시저 파라미터도 모니터링합니다.
**중요**  
각 문의 전체 SQL 텍스트는 중요한 데이터를 포함하여 활동 스트림 감사 로그에 표시됩니다. 그러나 데이터베이스 사용자 암호는 다음 SQL 문에서와 같이 Oracle이 컨텍스트에서 판별할 수 있는 경우 수정됩니다.  

  ```
  ALTER ROLE role-name WITH password
  ```
+ **연결 정보** – 모니터링되는 활동에는 세션 및 네트워크 정보, 서버 프로세스 ID 및 종료 코드가 포함됩니다.

DB 인스턴스를 모니터링하는 동안 활동 스트림에 오류가 발생하면 RDS 이벤트를 통해 사용자에게 알립니다.

다음 섹션에서는 데이터베이스 활동 스트림에 액세스하고, 이를 감사 및 처리할 수 있습니다.

**Topics**
+ [Amazon Kinesis에서 활동 스트림에 액세스](DBActivityStreams.KinesisAccess.md)
+ [데이터베이스 활동 스트림에 대한 감사 로그 내용 및 예제](DBActivityStreams.AuditLog.md)
+ [데이터베이스 활동 스트림에 대한 databaseActivityEventList JSON 배열](DBActivityStreams.AuditLog.databaseActivityEventList.md)
+ [AWS SDK를 사용하여 데이터베이스 활동 스트림 처리](DBActivityStreams.CodeExample.md)

# Amazon Kinesis에서 활동 스트림에 액세스
<a name="DBActivityStreams.KinesisAccess"></a>

데이터베이스에 대해 활동 스트림을 활성화하면 Kinesis 스트림이 생성됩니다. Kinesis에서 데이터베이스 활동을 실시간으로 모니터링할 수 있습니다. 데이터베이스 활동을 추가 분석하려면 Kinesis 스트림을 소비자 애플리케이션에 연결하면 됩니다. 또한 IBM의 Security Guardium 또는 Imperva의 SecureSphere Database Audit and Protection과 같은 규정 준수 관리 애플리케이션에 스트림을 연결할 수 있습니다.

RDS 콘솔 또는 Kinesis 콘솔에서 Kinesis 스트림에 액세스할 수 있습니다.

**RDS 콘솔을 사용하여 Kinesis에서 활동 스트림에 액세스하는 방법**

1. [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)에서 Amazon RDS 콘솔을 엽니다.

1. 탐색 창에서 **데이터베이스**를 선택합니다.

1. 활동 스트림을 시작한 Amazon RDS 데이터베이스 인스턴스를 선택합니다.

1. **Configuration**(구성)을 선택합니다.

1. **데이터베이스 활동 스트림**에서 **Kinesis 스트림** 아래의 링크를 선택합니다.

1. Kinesis 콘솔에서 **모니터링**을 선택하여 데이터베이스 활동 관찰을 시작합니다.

**Kinesis 콘솔을 사용하여 Kinesis에서 활동 스트림에 액세스하는 방법**

1. [https://console.aws.amazon.com/kinesis](https://console.aws.amazon.com/kinesis)에서 Kinesis 콘솔을 엽니다.

1. Kinesis 스트림 목록에서 활동 스트림을 선택합니다.

   활동 스트림의 이름에는 접두사 `aws-rds-das-db-`와 그 뒤의 데이터베이스의 리소스 ID가 포함됩니다. 다음은 예제입니다.

   ```
   aws-rds-das-db-NHVOV4PCLWHGF52NP
   ```

   Amazon RDS 콘솔을 사용하여 데이터베이스의 리소스 ID를 찾으려면 데이터베이스 목록에서 DB 인스턴스를 선택한 다음 **구성(Configuration)** 탭을 선택합니다.

   AWS CLI를 사용하여 활동 스트림의 전체 Kinesis 스트림 이름을 찾으려면 [describe-db-instances CLI](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) 요청을 사용하고 응답에서 `ActivityStreamKinesisStreamName` 값을 기록합니다.

1. 데이터베이스 활동을 관찰하려면 **모니터링**을 선택하십시오.

Amazon Kinesis 사용에 대한 자세한 내용은 [Amazon Kinesis Data Streams이란 무엇입니까?](https://docs.aws.amazon.com/streams/latest/dev/introduction.html)를 참조하십시오.

# 데이터베이스 활동 스트림에 대한 감사 로그 내용 및 예제
<a name="DBActivityStreams.AuditLog"></a>

모니터링되는 이벤트는 데이터베이스 활동 스트림에 JSON 문자열로 표시됩니다. 구조는 `DatabaseActivityMonitoringRecord`를 포함하는 JSON 객체로 구성되며, 여기에는 `databaseActivityEventList` 활동 이벤트 배열이 포함됩니다.

**참고**  
데이터베이스 활동 스트림의 경우 `paramList` JSON 배열에는 최대 절전 모드 애플리케이션의 null 값이 포함되지 않습니다.

**Topics**
+ [활동 스트림 감사 로그 예제](#DBActivityStreams.AuditLog.Examples)
+ [DatabaseActivityMonitoringRecords JSON 객체](#DBActivityStreams.AuditLog.DatabaseActivityMonitoringRecords)
+ [databaseActivityEvents JSON 객체](#DBActivityStreams.AuditLog.databaseActivityEvents)

## 활동 스트림 감사 로그 예제
<a name="DBActivityStreams.AuditLog.Examples"></a>

다음은 활동 이벤트 레코드의 해독된 JSON 감사 로그 샘플입니다.

**Example CONNECT SQL 문 의 활동 이벤트 레코드**  
다음 활동 이벤트 레코드는 Oracle DB의 JDBC 씬 클라이언트(`clientApplication`)에서 `CONNECT` SQL 문(`command`)을 사용하여 로그인한 것을 보여줍니다.  

```
{
    "class": "Standard",
    "clientApplication": "JDBC Thin Client",
    "command": "LOGON",
    "commandText": null,
    "dbid": "0123456789",
    "databaseName": "ORCL",
    "dbProtocol": "oracle",
    "dbUserName": "TEST",
    "endTime": null,
    "errorMessage": null,
    "exitCode": 0,
    "logTime": "2021-01-15 00:15:36.233787",
    "netProtocol": "tcp",
    "objectName": null,
    "objectType": null,
    "paramList": [],
    "pid": 17904,
    "remoteHost": "123.456.789.012",
    "remotePort": "25440",
    "rowCount": null,
    "serverHost": "987.654.321.098",
    "serverType": "oracle",
    "serverVersion": "19.0.0.0.ru-2020-01.rur-2020-01.r1.EE.3",
    "serviceName": "oracle-ee",
    "sessionId": 987654321,
    "startTime": null,
    "statementId": 1,
    "substatementId": null,
    "transactionId": "0000000000000000",
    "engineNativeAuditFields": {
        "UNIFIED_AUDIT_POLICIES": "TEST_POL_EVERYTHING",
        "FGA_POLICY_NAME": null,
        "DV_OBJECT_STATUS": null,
        "SYSTEM_PRIVILEGE_USED": "CREATE SESSION",
        "OLS_LABEL_COMPONENT_TYPE": null,
        "XS_SESSIONID": null,
        "ADDITIONAL_INFO": null,
        "INSTANCE_ID": 1,
        "DBID": 123456789
        "DV_COMMENT": null,
        "RMAN_SESSION_STAMP": null,
        "NEW_NAME": null,
        "DV_ACTION_NAME": null,
        "OLS_PROGRAM_UNIT_NAME": null,
        "OLS_STRING_LABEL": null,
        "RMAN_SESSION_RECID": null,
        "OBJECT_PRIVILEGES": null,
        "OLS_OLD_VALUE": null,
        "XS_TARGET_PRINCIPAL_NAME": null,
        "XS_NS_ATTRIBUTE": null,
        "XS_NS_NAME": null,
        "DBLINK_INFO": null,
        "AUTHENTICATION_TYPE": "(TYPE\u003d(DATABASE));(CLIENT ADDRESS\u003d((ADDRESS\u003d(PROTOCOL\u003dtcp)(HOST\u003d205.251.233.183)(PORT\u003d25440))));",
        "OBJECT_EDITION": null,
        "OLS_PRIVILEGES_GRANTED": null,
        "EXCLUDED_USER": null,
        "DV_ACTION_OBJECT_NAME": null,
        "OLS_LABEL_COMPONENT_NAME": null,
        "EXCLUDED_SCHEMA": null,
        "DP_TEXT_PARAMETERS1": null,
        "XS_USER_NAME": null,
        "XS_ENABLED_ROLE": null,
        "XS_NS_ATTRIBUTE_NEW_VAL": null,
        "DIRECT_PATH_NUM_COLUMNS_LOADED": null,
        "AUDIT_OPTION": null,
        "DV_EXTENDED_ACTION_CODE": null,
        "XS_PACKAGE_NAME": null,
        "OLS_NEW_VALUE": null,
        "DV_RETURN_CODE": null,
        "XS_CALLBACK_EVENT_TYPE": null,
        "USERHOST": "a1b2c3d4e5f6.amazon.com",
        "GLOBAL_USERID": null,
        "CLIENT_IDENTIFIER": null,
        "RMAN_OPERATION": null,
        "TERMINAL": "unknown",
        "OS_USERNAME": "sumepate",
        "OLS_MAX_READ_LABEL": null,
        "XS_PROXY_USER_NAME": null,
        "XS_DATASEC_POLICY_NAME": null,
        "DV_FACTOR_CONTEXT": null,
        "OLS_MAX_WRITE_LABEL": null,
        "OLS_PARENT_GROUP_NAME": null,
        "EXCLUDED_OBJECT": null,
        "DV_RULE_SET_NAME": null,
        "EXTERNAL_USERID": null,
        "EXECUTION_ID": null,
        "ROLE": null,
        "PROXY_SESSIONID": 0,
        "DP_BOOLEAN_PARAMETERS1": null,
        "OLS_POLICY_NAME": null,
        "OLS_GRANTEE": null,
        "OLS_MIN_WRITE_LABEL": null,
        "APPLICATION_CONTEXTS": null,
        "XS_SCHEMA_NAME": null,
        "DV_GRANTEE": null,
        "XS_COOKIE": null,
        "DBPROXY_USERNAME": null,
        "DV_ACTION_CODE": null,
        "OLS_PRIVILEGES_USED": null,
        "RMAN_DEVICE_TYPE": null,
        "XS_NS_ATTRIBUTE_OLD_VAL": null,
        "TARGET_USER": null,
        "XS_ENTITY_TYPE": null,
        "ENTRY_ID": 1,
        "XS_PROCEDURE_NAME": null,
        "XS_INACTIVITY_TIMEOUT": null,
        "RMAN_OBJECT_TYPE": null,
        "SYSTEM_PRIVILEGE": null,
        "NEW_SCHEMA": null,
        "SCN": 5124715
    }
}
```
다음 활동 이벤트 레코드는 SQL Server DB의 로그인 실패를 보여줍니다.  

```
{
    "type": "DatabaseActivityMonitoringRecord",
    "clusterId": "",
    "instanceId": "db-4JCWQLUZVFYP7DIWP6JVQ77O3Q",
    "databaseActivityEventList": [
        {
            "class": "LOGIN",
            "clientApplication": "Microsoft SQL Server Management Studio",
            "command": "LOGIN FAILED",
            "commandText": "Login failed for user 'test'. Reason: Password did not match that for the login provided. [CLIENT: local-machine]",
            "databaseName": "",
            "dbProtocol": "SQLSERVER",
            "dbUserName": "test",
            "endTime": null,
            "errorMessage": null,
            "exitCode": 0,
            "logTime": "2022-10-06 21:34:42.7113072+00",
            "netProtocol": null,
            "objectName": "",
            "objectType": "LOGIN",
            "paramList": null,
            "pid": null,
            "remoteHost": "local machine",
            "remotePort": null,
            "rowCount": 0,
            "serverHost": "172.31.30.159",
            "serverType": "SQLSERVER",
            "serverVersion": "15.00.4073.23.v1.R1",
            "serviceName": "sqlserver-ee",
            "sessionId": 0,
            "startTime": null,
            "statementId": "0x1eb0d1808d34a94b9d3dcf5432750f02",
            "substatementId": 1,
            "transactionId": "0",
            "type": "record",
            "engineNativeAuditFields": {
                "target_database_principal_id": 0,
                "target_server_principal_id": 0,
                "target_database_principal_name": "",
                "server_principal_id": 0,
                "user_defined_information": "",
                "response_rows": 0,
                "database_principal_name": "",
                "target_server_principal_name": "",
                "schema_name": "",
                "is_column_permission": false,
                "object_id": 0,
                "server_instance_name": "EC2AMAZ-NFUJJNO",
                "target_server_principal_sid": null,
                "additional_information": "<action_info "xmlns=\"http://schemas.microsoft.com/sqlserver/2008/sqlaudit_data\"><pooled_connection>0</pooled_connection><error>0x00004818</error><state>8</state><address>local machine</address><PasswordFirstNibbleHash>B</PasswordFirstNibbleHash></action_info>"-->,
                "duration_milliseconds": 0,
                "permission_bitmask": "0x00000000000000000000000000000000",
                "data_sensitivity_information": "",
                "session_server_principal_name": "",
                "connection_id": "98B4F537-0F82-49E3-AB08-B9D33B5893EF",
                "audit_schema_version": 1,
                "database_principal_id": 0,
                "server_principal_sid": null,
                "user_defined_event_id": 0,
                "host_name": "EC2AMAZ-NFUJJNO"
            }
        }
    ]
}
```
데이터베이스 활동 스트림이 활성화되지 않은 경우 JSON 문서의 마지막 필드는 `"engineNativeAuditFields": { }`입니다.

**Example CREATE TABLE 문의 활동 이벤트 레코드**  
다음 예시는 Oracle 데이터베이스에 대한 `CREATE TABLE` 이벤트를 보여줍니다.  

```
{
    "class": "Standard",
    "clientApplication": "sqlplus@ip-12-34-5-678 (TNS V1-V3)",
    "command": "CREATE TABLE",
    "commandText": "CREATE TABLE persons(\n    person_id NUMBER GENERATED BY DEFAULT AS IDENTITY,\n    first_name VARCHAR2(50) NOT NULL,\n    last_name VARCHAR2(50) NOT NULL,\n    PRIMARY KEY(person_id)\n)",
    "dbid": "0123456789",
    "databaseName": "ORCL",
    "dbProtocol": "oracle",
    "dbUserName": "TEST",
    "endTime": null,
    "errorMessage": null,
    "exitCode": 0,
    "logTime": "2021-01-15 00:22:49.535239",
    "netProtocol": "beq",
    "objectName": "PERSONS",
    "objectType": "TEST",
    "paramList": [],
    "pid": 17687,
    "remoteHost": "123.456.789.0",
    "remotePort": null,
    "rowCount": null,
    "serverHost": "987.654.321.01",
    "serverType": "oracle",
    "serverVersion": "19.0.0.0.ru-2020-01.rur-2020-01.r1.EE.3",
    "serviceName": "oracle-ee",
    "sessionId": 1234567890,
    "startTime": null,
    "statementId": 43,
    "substatementId": null,
    "transactionId": "090011007F0D0000",
    "engineNativeAuditFields": {
        "UNIFIED_AUDIT_POLICIES": "TEST_POL_EVERYTHING",
        "FGA_POLICY_NAME": null,
        "DV_OBJECT_STATUS": null,
        "SYSTEM_PRIVILEGE_USED": "CREATE SEQUENCE, CREATE TABLE",
        "OLS_LABEL_COMPONENT_TYPE": null,
        "XS_SESSIONID": null,
        "ADDITIONAL_INFO": null,
        "INSTANCE_ID": 1,
        "DV_COMMENT": null,
        "RMAN_SESSION_STAMP": null,
        "NEW_NAME": null,
        "DV_ACTION_NAME": null,
        "OLS_PROGRAM_UNIT_NAME": null,
        "OLS_STRING_LABEL": null,
        "RMAN_SESSION_RECID": null,
        "OBJECT_PRIVILEGES": null,
        "OLS_OLD_VALUE": null,
        "XS_TARGET_PRINCIPAL_NAME": null,
        "XS_NS_ATTRIBUTE": null,
        "XS_NS_NAME": null,
        "DBLINK_INFO": null,
        "AUTHENTICATION_TYPE": "(TYPE\u003d(DATABASE));(CLIENT ADDRESS\u003d((PROTOCOL\u003dbeq)(HOST\u003d123.456.789.0)));",
        "OBJECT_EDITION": null,
        "OLS_PRIVILEGES_GRANTED": null,
        "EXCLUDED_USER": null,
        "DV_ACTION_OBJECT_NAME": null,
        "OLS_LABEL_COMPONENT_NAME": null,
        "EXCLUDED_SCHEMA": null,
        "DP_TEXT_PARAMETERS1": null,
        "XS_USER_NAME": null,
        "XS_ENABLED_ROLE": null,
        "XS_NS_ATTRIBUTE_NEW_VAL": null,
        "DIRECT_PATH_NUM_COLUMNS_LOADED": null,
        "AUDIT_OPTION": null,
        "DV_EXTENDED_ACTION_CODE": null,
        "XS_PACKAGE_NAME": null,
        "OLS_NEW_VALUE": null,
        "DV_RETURN_CODE": null,
        "XS_CALLBACK_EVENT_TYPE": null,
        "USERHOST": "ip-10-13-0-122",
        "GLOBAL_USERID": null,
        "CLIENT_IDENTIFIER": null,
        "RMAN_OPERATION": null,
        "TERMINAL": "pts/1",
        "OS_USERNAME": "rdsdb",
        "OLS_MAX_READ_LABEL": null,
        "XS_PROXY_USER_NAME": null,
        "XS_DATASEC_POLICY_NAME": null,
        "DV_FACTOR_CONTEXT": null,
        "OLS_MAX_WRITE_LABEL": null,
        "OLS_PARENT_GROUP_NAME": null,
        "EXCLUDED_OBJECT": null,
        "DV_RULE_SET_NAME": null,
        "EXTERNAL_USERID": null,
        "EXECUTION_ID": null,
        "ROLE": null,
        "PROXY_SESSIONID": 0,
        "DP_BOOLEAN_PARAMETERS1": null,
        "OLS_POLICY_NAME": null,
        "OLS_GRANTEE": null,
        "OLS_MIN_WRITE_LABEL": null,
        "APPLICATION_CONTEXTS": null,
        "XS_SCHEMA_NAME": null,
        "DV_GRANTEE": null,
        "XS_COOKIE": null,
        "DBPROXY_USERNAME": null,
        "DV_ACTION_CODE": null,
        "OLS_PRIVILEGES_USED": null,
        "RMAN_DEVICE_TYPE": null,
        "XS_NS_ATTRIBUTE_OLD_VAL": null,
        "TARGET_USER": null,
        "XS_ENTITY_TYPE": null,
        "ENTRY_ID": 12,
        "XS_PROCEDURE_NAME": null,
        "XS_INACTIVITY_TIMEOUT": null,
        "RMAN_OBJECT_TYPE": null,
        "SYSTEM_PRIVILEGE": null,
        "NEW_SCHEMA": null,
        "SCN": 5133083
    }
}
```
다음 예시는 SQL Server 데이터베이스의 `CREATE TABLE` 이벤트를 보여줍니다.  

```
{
    "type": "DatabaseActivityMonitoringRecord",
    "clusterId": "",
    "instanceId": "db-4JCWQLUZVFYP7DIWP6JVQ77O3Q",
    "databaseActivityEventList": [
        {
            "class": "SCHEMA",
            "clientApplication": "Microsoft SQL Server Management Studio - Query",
            "command": "ALTER",
            "commandText": "Create table [testDB].[dbo].[TestTable2](\r\ntextA varchar(6000),\r\n    textB varchar(6000)\r\n)",
            "databaseName": "testDB",
            "dbProtocol": "SQLSERVER",
            "dbUserName": "test",
            "endTime": null,
            "errorMessage": null,
            "exitCode": 1,
            "logTime": "2022-10-06 21:44:38.4120677+00",
            "netProtocol": null,
            "objectName": "dbo",
            "objectType": "SCHEMA",
            "paramList": null,
            "pid": null,
            "remoteHost": "local machine",
            "remotePort": null,
            "rowCount": 0,
            "serverHost": "172.31.30.159",
            "serverType": "SQLSERVER",
            "serverVersion": "15.00.4073.23.v1.R1",
            "serviceName": "sqlserver-ee",
            "sessionId": 84,
            "startTime": null,
            "statementId": "0x5178d33d56e95e419558b9607158a5bd",
            "substatementId": 1,
            "transactionId": "4561864",
            "type": "record",
            "engineNativeAuditFields": {
                "target_database_principal_id": 0,
                "target_server_principal_id": 0,
                "target_database_principal_name": "",
                "server_principal_id": 2,
                "user_defined_information": "",
                "response_rows": 0,
                "database_principal_name": "dbo",
                "target_server_principal_name": "",
                "schema_name": "",
                "is_column_permission": false,
                "object_id": 1,
                "server_instance_name": "EC2AMAZ-NFUJJNO",
                "target_server_principal_sid": null,
                "additional_information": "",
                "duration_milliseconds": 0,
                "permission_bitmask": "0x00000000000000000000000000000000",
                "data_sensitivity_information": "",
                "session_server_principal_name": "test",
                "connection_id": "EE1FE3FD-EF2C-41FD-AF45-9051E0CD983A",
                "audit_schema_version": 1,
                "database_principal_id": 1,
                "server_principal_sid": "0x010500000000000515000000bdc2795e2d0717901ba6998cf4010000",
                "user_defined_event_id": 0,
                "host_name": "EC2AMAZ-NFUJJNO"
            }
        }
    ]
}
```

**Example SELECT 문의 활동 이벤트 레코드**  
다음 예시는 Oracle DB에 대한 `SELECT` 이벤트를 보여줍니다.  

```
{
    "class": "Standard",
    "clientApplication": "sqlplus@ip-12-34-5-678 (TNS V1-V3)",
    "command": "SELECT",
    "commandText": "select count(*) from persons",
    "databaseName": "1234567890",
    "dbProtocol": "oracle",
    "dbUserName": "TEST",
    "endTime": null,
    "errorMessage": null,
    "exitCode": 0,
    "logTime": "2021-01-15 00:25:18.850375",
    "netProtocol": "beq",
    "objectName": "PERSONS",
    "objectType": "TEST",
    "paramList": [],
    "pid": 17687,
    "remoteHost": "123.456.789.0",
    "remotePort": null,
    "rowCount": null,
    "serverHost": "987.654.321.09",
    "serverType": "oracle",
    "serverVersion": "19.0.0.0.ru-2020-01.rur-2020-01.r1.EE.3",
    "serviceName": "oracle-ee",
    "sessionId": 1080639707,
    "startTime": null,
    "statementId": 44,
    "substatementId": null,
    "transactionId": null,
    "engineNativeAuditFields": {
        "UNIFIED_AUDIT_POLICIES": "TEST_POL_EVERYTHING",
        "FGA_POLICY_NAME": null,
        "DV_OBJECT_STATUS": null,
        "SYSTEM_PRIVILEGE_USED": null,
        "OLS_LABEL_COMPONENT_TYPE": null,
        "XS_SESSIONID": null,
        "ADDITIONAL_INFO": null,
        "INSTANCE_ID": 1,
        "DV_COMMENT": null,
        "RMAN_SESSION_STAMP": null,
        "NEW_NAME": null,
        "DV_ACTION_NAME": null,
        "OLS_PROGRAM_UNIT_NAME": null,
        "OLS_STRING_LABEL": null,
        "RMAN_SESSION_RECID": null,
        "OBJECT_PRIVILEGES": null,
        "OLS_OLD_VALUE": null,
        "XS_TARGET_PRINCIPAL_NAME": null,
        "XS_NS_ATTRIBUTE": null,
        "XS_NS_NAME": null,
        "DBLINK_INFO": null,
        "AUTHENTICATION_TYPE": "(TYPE\u003d(DATABASE));(CLIENT ADDRESS\u003d((PROTOCOL\u003dbeq)(HOST\u003d123.456.789.0)));",
        "OBJECT_EDITION": null,
        "OLS_PRIVILEGES_GRANTED": null,
        "EXCLUDED_USER": null,
        "DV_ACTION_OBJECT_NAME": null,
        "OLS_LABEL_COMPONENT_NAME": null,
        "EXCLUDED_SCHEMA": null,
        "DP_TEXT_PARAMETERS1": null,
        "XS_USER_NAME": null,
        "XS_ENABLED_ROLE": null,
        "XS_NS_ATTRIBUTE_NEW_VAL": null,
        "DIRECT_PATH_NUM_COLUMNS_LOADED": null,
        "AUDIT_OPTION": null,
        "DV_EXTENDED_ACTION_CODE": null,
        "XS_PACKAGE_NAME": null,
        "OLS_NEW_VALUE": null,
        "DV_RETURN_CODE": null,
        "XS_CALLBACK_EVENT_TYPE": null,
        "USERHOST": "ip-12-34-5-678",
        "GLOBAL_USERID": null,
        "CLIENT_IDENTIFIER": null,
        "RMAN_OPERATION": null,
        "TERMINAL": "pts/1",
        "OS_USERNAME": "rdsdb",
        "OLS_MAX_READ_LABEL": null,
        "XS_PROXY_USER_NAME": null,
        "XS_DATASEC_POLICY_NAME": null,
        "DV_FACTOR_CONTEXT": null,
        "OLS_MAX_WRITE_LABEL": null,
        "OLS_PARENT_GROUP_NAME": null,
        "EXCLUDED_OBJECT": null,
        "DV_RULE_SET_NAME": null,
        "EXTERNAL_USERID": null,
        "EXECUTION_ID": null,
        "ROLE": null,
        "PROXY_SESSIONID": 0,
        "DP_BOOLEAN_PARAMETERS1": null,
        "OLS_POLICY_NAME": null,
        "OLS_GRANTEE": null,
        "OLS_MIN_WRITE_LABEL": null,
        "APPLICATION_CONTEXTS": null,
        "XS_SCHEMA_NAME": null,
        "DV_GRANTEE": null,
        "XS_COOKIE": null,
        "DBPROXY_USERNAME": null,
        "DV_ACTION_CODE": null,
        "OLS_PRIVILEGES_USED": null,
        "RMAN_DEVICE_TYPE": null,
        "XS_NS_ATTRIBUTE_OLD_VAL": null,
        "TARGET_USER": null,
        "XS_ENTITY_TYPE": null,
        "ENTRY_ID": 13,
        "XS_PROCEDURE_NAME": null,
        "XS_INACTIVITY_TIMEOUT": null,
        "RMAN_OBJECT_TYPE": null,
        "SYSTEM_PRIVILEGE": null,
        "NEW_SCHEMA": null,
        "SCN": 5136972
    }
}
```
다음 예시는 SQL Server DB에 대한 `SELECT` 이벤트를 보여줍니다.  

```
{
    "type": "DatabaseActivityMonitoringRecord",
    "clusterId": "",
    "instanceId": "db-4JCWQLUZVFYP7DIWP6JVQ77O3Q",
    "databaseActivityEventList": [
        {
            "class": "TABLE",
            "clientApplication": "Microsoft SQL Server Management Studio - Query",
            "command": "SELECT",
            "commandText": "select * from [testDB].[dbo].[TestTable]",
            "databaseName": "testDB",
            "dbProtocol": "SQLSERVER",
            "dbUserName": "test",
            "endTime": null,
            "errorMessage": null,
            "exitCode": 1,
            "logTime": "2022-10-06 21:24:59.9422268+00",
            "netProtocol": null,
            "objectName": "TestTable",
            "objectType": "TABLE",
            "paramList": null,
            "pid": null,
            "remoteHost": "local machine",
            "remotePort": null,
            "rowCount": 0,
            "serverHost": "172.31.30.159",
            "serverType": "SQLSERVER",
            "serverVersion": "15.00.4073.23.v1.R1",
            "serviceName": "sqlserver-ee",
            "sessionId": 62,
            "startTime": null,
            "statementId": "0x03baed90412f564fad640ebe51f89b99",
            "substatementId": 1,
            "transactionId": "4532935",
            "type": "record",
            "engineNativeAuditFields": {
                "target_database_principal_id": 0,
                "target_server_principal_id": 0,
                "target_database_principal_name": "",
                "server_principal_id": 2,
                "user_defined_information": "",
                "response_rows": 0,
                "database_principal_name": "dbo",
                "target_server_principal_name": "",
                "schema_name": "dbo",
                "is_column_permission": true,
                "object_id": 581577110,
                "server_instance_name": "EC2AMAZ-NFUJJNO",
                "target_server_principal_sid": null,
                "additional_information": "",
                "duration_milliseconds": 0,
                "permission_bitmask": "0x00000000000000000000000000000001",
                "data_sensitivity_information": "",
                "session_server_principal_name": "test",
                "connection_id": "AD3A5084-FB83-45C1-8334-E923459A8109",
                "audit_schema_version": 1,
                "database_principal_id": 1,
                "server_principal_sid": "0x010500000000000515000000bdc2795e2d0717901ba6998cf4010000",
                "user_defined_event_id": 0,
                "host_name": "EC2AMAZ-NFUJJNO"
            }
        }
    ]
}
```

## DatabaseActivityMonitoringRecords JSON 객체
<a name="DBActivityStreams.AuditLog.DatabaseActivityMonitoringRecords"></a>

데이터베이스 작업 이벤트 레코드는 다음 정보가 포함된 JSON 객체에 있습니다.


****  

| JSON 필드 | 데이터 형식 | 설명 | 
| --- | --- | --- | 
|  `type`  | string |  JSON 레코드 형식입니다. 이 값은 `DatabaseActivityMonitoringRecords`입니다.  | 
| version | string |  데이터베이스 작업 모니터링 레코드의 버전입니다. Oracle DB는 버전 1.3을 사용하고 SQL Server는 버전 1.4를 사용합니다. 이러한 엔진 버전에는 engineNativeAuditFields JSON 객체가 도입됩니다.  | 
|  [databaseActivityEvents](#DBActivityStreams.AuditLog.databaseActivityEvents)  | 문자열 |  작업 이벤트를 포함하는 JSON 객체입니다.  | 
| 키 | 문자열 | [databaseActivityEventList JSON 배열](DBActivityStreams.AuditLog.databaseActivityEventList.md)를 해독하는 데 사용되는 암호화 키  | 

## databaseActivityEvents JSON 객체
<a name="DBActivityStreams.AuditLog.databaseActivityEvents"></a>

`databaseActivityEvents` JSON 객체에는 다음과 같은 정보가 포함되어 있습니다.

### JSON 레코드의 최상위 필드
<a name="DBActivityStreams.AuditLog.topLevel"></a>

 감사 로그의 각 이벤트는 JSON 형식의 레코드 내에 래핑됩니다. 이 레코드에는 다음 필드가 포함되어 있습니다.

**type**  
 이 필드는 항상 값이 `DatabaseActivityMonitoringRecords`입니다.

**version**  
 이 필드는 데이터베이스 활동 스트림 데이터 프로토콜 또는 계약 버전을 나타냅니다. 이는 사용 가능한 필드를 정의합니다.

**databaseActivityEvents**  
 하나 이상의 활동 이벤트를 나타내는 암호화된 문자열입니다. base64 바이트 배열로 표현됩니다. 문자열을 해독하면 결과는 이 단원의 예제와 같이 필드가 있는 JSON 형식의 레코드입니다.

**키**  
 `databaseActivityEvents` 문자열을 암호화하는 데 사용되는 암호화된 데이터 키입니다. 이 키는 데이터베이스 활동 스트림을 시작할 때 제공한 AWS KMS key와(과) 동일합니다.

 다음 예제에서는 이 레코드의 형식을 보여줍니다.

```
{
  "type":"DatabaseActivityMonitoringRecords",
  "version":"1.3",
  "databaseActivityEvents":"encrypted audit records",
  "key":"encrypted key"
}
```

```
           "type":"DatabaseActivityMonitoringRecords",
           "version":"1.4",
           "databaseActivityEvents":"encrypted audit records",
           "key":"encrypted key"
```

`databaseActivityEvents` 필드의 내용을 해독하려면 다음 단계를 수행합니다.

1.  데이터베이스 활동 스트림을 시작할 때 제공한 키를 사용하여 `key` JSON 필드의 값을 복호화합니다. 이렇게 하면 데이터 암호화 키가 일반 텍스트로 반환됩니다.

1.  Base64로 `databaseActivityEvents` JSON 필드의 값을 디코딩하여 감사 페이로드의 암호화 텍스트를 이진 형식으로 가져옵니다.

1.  첫 번째 단계에서 디코딩한 데이터 암호화 키를 사용하여 이진 암호화 텍스트를 해독합니다.

1.  해독된 페이로드의 압축을 풉니다.
   +  암호화된 페이로드가 `databaseActivityEvents` 필드에 있습니다.
   +  `databaseActivityEventList` 필드에는 감사 레코드 배열이 포함되어 있습니다. 배열의 `type` 필드는 `record` 또는 `heartbeat`일 수 있습니다.

감사 로그 활동 이벤트 레코드는 다음 정보가 포함된 JSON 객체입니다.


****  

| JSON 필드 | 데이터 형식 | 설명 | 
| --- | --- | --- | 
|  `type`  | string |  JSON 레코드 형식입니다. 이 값은 `DatabaseActivityMonitoringRecord`입니다.  | 
| instanceId | string | DB 인스턴스 리소스 식별자입니다. DB 인스턴스 속성 DbiResourceId에 해당합니다. | 
|  [databaseActivityEventList JSON 배열](DBActivityStreams.AuditLog.databaseActivityEventList.md)   | string |  활동 감사 레코드 또는 하트비트 메시지의 배열입니다.  | 

# 데이터베이스 활동 스트림에 대한 databaseActivityEventList JSON 배열
<a name="DBActivityStreams.AuditLog.databaseActivityEventList"></a>

감사 로그 페이로드는 암호화된 `databaseActivityEventList` JSON 배열입니다. 다음 표에는 감사 로그의 복호화된 `DatabaseActivityEventList` 배열에 있는 각 활동 이벤트의 필드가 알파벳 순으로 나열되어 있습니다. 

Oracle 데이터베이스에서 통합 감사가 활성화된 경우 이 새 감사 추적에 감사 레코드가 채워집니다. `UNIFIED_AUDIT_TRAIL` 보기는 감사 추적에서 감사 레코드를 검색하여 감사 레코드를 테이블 형식으로 표시합니다. 데이터베이스 활동 스트림을 시작하려면 `UNIFIED_AUDIT_TRAIL`의 열이 `databaseActivityEventList` 배열의 필드에 매핑됩니다.

**중요**  
이벤트 구조는 변경될 수 있습니다. Amazon RDS는 향후 활동 이벤트에 새 필드를 추가할 수 있습니다. JSON 데이터를 구문 분석하는 애플리케이션에서 코드는 알 수 없는 필드 이름에 대해 무시할 수 있는지 또는 적절한 작업을 수행할 수 있는지 확인합니다.

## Amazon RDS for Oracle에 대한 databaseActivityEventList 필드
<a name="DBActivityStreams.AuditLog.databaseActivityEventList.ro"></a>

Amazon RDS for Oracle에 대한 `databaseActivityEventList` 필드는 다음과 같습니다.


| 필드 | 데이터 형식 | 소스 | 설명 | 
| --- | --- | --- | --- | 
|  `class`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `AUDIT_TYPE` 열  |  활동 이벤트의 클래스입니다. 이는 `UNIFIED_AUDIT_TRAIL` 보기의 `AUDIT_TYPE` 열에 해당합니다. Amazon RDS for Oracle에 대한 유효한 값은 다음과 같습니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/DBActivityStreams.AuditLog.databaseActivityEventList.html) 자세한 내용은 Oracle 문서의 [UNIFIED\$1AUDIT\$1TRAIL](https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/UNIFIED_AUDIT_TRAIL.html#GUID-B7CE1C02-2FD4-47D6-80AA-CF74A60CDD1D)을 참조하세요.  | 
|  `clientApplication`  |  string  |  `CLIENT_PROGRAM_NAME`의 `UNIFIED_AUDIT_TRAIL`  |  클라이언트가 보고한 대로 클라이언트가 연결에 사용한 애플리케이션입니다. 클라이언트는 이 정보를 제공할 필요가 없으므로 값은 null일 수 있습니다. 샘플 값은 `JDBC Thin Client`입니다.  | 
|  `command`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `ACTION_NAME` 열  |  사용자가 실행한 작업 이름입니다. 전체 작업을 이해하려면 명령 이름과 `AUDIT_TYPE` 값을 숙지합니다. 샘플 값은 `ALTER DATABASE`입니다.  | 
|  `commandText`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `SQL_TEXT` 열  |  이벤트와 연결된 SQL 문 샘플 값은 `ALTER DATABASE BEGIN BACKUP`입니다.  | 
|  `databaseName`  |  string  |  `V$DATABASE`의 `NAME` 열  |  데이터베이스의 이름입니다.  | 
|  `dbid`  |  숫자  |  `UNIFIED_AUDIT_TRAIL`의 `DBID` 열  |  데이터베이스의 숫자 식별자입니다. 샘플 값은 `1559204751`입니다.  | 
|  `dbProtocol`  |  string  |  해당 사항 없음  |  데이터베이스 프로토콜. 이 베타에서 값은 `oracle`입니다.  | 
|  `dbUserName`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `DBUSERNAME` 열  |  작업이 감사된 데이터베이스 사용자의 이름입니다. 샘플 값은 `RDSADMIN`입니다.  | 
|  `endTime`  |  string  |  해당 사항 없음  |  이 필드는 RDS for Oracle에 사용되지 않으며 항상 null입니다.  | 
|  `engineNativeAuditFields`  |  객체  |  `UNIFIED_AUDIT_TRAIL`  |  기본적으로 이 객체는 비어 있습니다. `--engine-native-audit-fields-included` 옵션을 사용하여 활동 스트림을 시작하면 이 객체에는 다음과 같은 열과 값이 포함됩니다. <pre>ADDITIONAL_INFO<br />APPLICATION_CONTEXTS<br />AUDIT_OPTION<br />AUTHENTICATION_TYPE<br />CLIENT_IDENTIFIER<br />CURRENT_USER<br />DBLINK_INFO<br />DBPROXY_USERNAME<br />DIRECT_PATH_NUM_COLUMNS_LOADED<br />DP_BOOLEAN_PARAMETERS1<br />DP_TEXT_PARAMETERS1<br />DV_ACTION_CODE<br />DV_ACTION_NAME<br />DV_ACTION_OBJECT_NAME<br />DV_COMMENT<br />DV_EXTENDED_ACTION_CODE<br />DV_FACTOR_CONTEXT<br />DV_GRANTEE<br />DV_OBJECT_STATUS<br />DV_RETURN_CODE<br />DV_RULE_SET_NAME<br />ENTRY_ID<br />EXCLUDED_OBJECT<br />EXCLUDED_SCHEMA<br />EXCLUDED_USER<br />EXECUTION_ID<br />EXTERNAL_USERID<br />FGA_POLICY_NAME<br />GLOBAL_USERID<br />INSTANCE_ID<br />KSACL_SERVICE_NAME<br />KSACL_SOURCE_LOCATION<br />KSACL_USER_NAME<br />NEW_NAME<br />NEW_SCHEMA<br />OBJECT_EDITION<br />OBJECT_PRIVILEGES<br />OLS_GRANTEE<br />OLS_LABEL_COMPONENT_NAME<br />OLS_LABEL_COMPONENT_TYPE<br />OLS_MAX_READ_LABEL<br />OLS_MAX_WRITE_LABEL<br />OLS_MIN_WRITE_LABEL<br />OLS_NEW_VALUE<br />OLS_OLD_VALUE<br />OLS_PARENT_GROUP_NAME<br />OLS_POLICY_NAME<br />OLS_PRIVILEGES_GRANTED<br />OLS_PRIVILEGES_USED<br />OLS_PROGRAM_UNIT_NAME<br />OLS_STRING_LABEL<br />OS_USERNAME<br />PROTOCOL_ACTION_NAME<br />PROTOCOL_MESSAGE<br />PROTOCOL_RETURN_CODE<br />PROTOCOL_SESSION_ID<br />PROTOCOL_USERHOST<br />PROXY_SESSIONID<br />RLS_INFO<br />RMAN_DEVICE_TYPE<br />RMAN_OBJECT_TYPE<br />RMAN_OPERATION<br />RMAN_SESSION_RECID<br />RMAN_SESSION_STAMP<br />ROLE<br />SCN<br />SYSTEM_PRIVILEGE<br />SYSTEM_PRIVILEGE_USED<br />TARGET_USER<br />TERMINAL<br />UNIFIED_AUDIT_POLICIES<br />USERHOST<br />XS_CALLBACK_EVENT_TYPE<br />XS_COOKIE<br />XS_DATASEC_POLICY_NAME<br />XS_ENABLED_ROLE<br />XS_ENTITY_TYPE<br />XS_INACTIVITY_TIMEOUT<br />XS_NS_ATTRIBUTE<br />XS_NS_ATTRIBUTE_NEW_VAL<br />XS_NS_ATTRIBUTE_OLD_VAL<br />XS_NS_NAME<br />XS_PACKAGE_NAME<br />XS_PROCEDURE_NAME<br />XS_PROXY_USER_NAME<br />XS_SCHEMA_NAME<br />XS_SESSIONID<br />XS_TARGET_PRINCIPAL_NAME<br />XS_USER_NAME</pre> 자세한 내용은 Oracle 데이터베이스 문서의 [UNIFIED\$1AUDIT\$1TRAIL](https://docs.oracle.com/database/121/REFRN/GUID-B7CE1C02-2FD4-47D6-80AA-CF74A60CDD1D.htm#REFRN29162)을 참조하세요.  | 
|  `errorMessage`  |  string  |  해당 사항 없음  |  이 필드는 RDS for Oracle에 사용되지 않으며 항상 null입니다.  | 
|  `exitCode`  |  숫자  |  `UNIFIED_AUDIT_TRAIL`의 `RETURN_CODE` 열  |  작업으로 인해 생성된 Oracle 데이터베이스 오류 코드입니다. 작업이 성공한 경우 값은 `0`입니다.  | 
|  `logTime`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `EVENT_TIMESTAMP_UTC` 열  |  감사 추적 항목 작성에 대한 타임스탬프입니다. 샘플 값은 `2020-11-27 06:56:14.981404`입니다.  | 
|  `netProtocol`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `AUTHENTICATION_TYPE` 열  |  네트워크 통신 프로토콜. 샘플 값은 `TCP`입니다.  | 
|  `objectName`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `OBJECT_NAME` 열  |  작업의 영향을 받는 객체의 이름입니다. 샘플 값은 `employees`입니다.  | 
|  `objectType`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `OBJECT_SCHEMA` 열  |  작업의 영향을 받는 객체의 스키마 이름입니다. 샘플 값은 `hr`입니다.  | 
|  `paramList`  |  목록  |  `UNIFIED_AUDIT_TRAIL`의 `SQL_BINDS` 열  |  해당되는 경우 `SQL_TEXT`와 관련된 경우 바인딩 변수 목록입니다. 샘플 값은 `parameter_1,parameter_2`입니다.  | 
|  `pid`  |  숫자  |  `UNIFIED_AUDIT_TRAIL`의 `OS_PROCESS` 열  |  Oracle 데이터베이스 프로세스의 운영 체제 프로세스 식별자입니다. 샘플 값은 `22396`입니다.  | 
|  `remoteHost`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `AUTHENTICATION_TYPE` 열  |  세션을 생성한 호스트의 클라이언트 IP 주소 또는 클라이언트 이름입니다. 샘플 값은 `123.456.789.123`입니다.  | 
|  `remotePort`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `AUTHENTICATION_TYPE` 열  |  클라이언트 포트 번호. Oracle 데이터베이스 환경의 일반적인 값은 `1521`입니다.  | 
|  `rowCount`  |  숫자  |  해당 사항 없음  |  이 필드는 RDS for Oracle에 사용되지 않으며 항상 null입니다.  | 
|  `serverHost`  |  string  |  데이터베이스 호스트  |  데이터베이스 서버 호스트 IP 주소. 샘플 값은 `123.456.789.123`입니다.  | 
|  `serverType`  |  string  |  해당 사항 없음  |  데이터베이스 서버 유형입니다. 이 값은 항상 `ORACLE`입니다.  | 
|  `serverVersion`  |  string  |  데이터베이스 호스트  |  Amazon RDS for Oracle 버전, RU(릴리스 업데이트) 및 RUR(릴리스 업데이트 버전) 샘플 값은 `19.0.0.0.ru-2020-01.rur-2020-01.r1.EE.3`입니다.  | 
|  `serviceName`  |  string  |  데이터베이스 호스트  |  서비스의 이름입니다. 샘플 값은 `oracle-ee`입니다.  | 
|  `sessionId`  |  숫자  |  `UNIFIED_AUDIT_TRAIL`의 `SESSIONID` 열  |  감사의 세션 식별자입니다. 예를 들면, `1894327130`입니다.  | 
|  `startTime`  |  string  |  해당 사항 없음  |  이 필드는 RDS for Oracle에 사용되지 않으며 항상 null입니다.  | 
|  `statementId`  |  숫자  |  `UNIFIED_AUDIT_TRAIL`의 `STATEMENT_ID` 열  |  각 문 실행에 대한 숫자 ID입니다. 문은 많은 작업을 일으킬 수 있습니다. 샘플 값은 `142197`입니다.  | 
|  `substatementId`  |  해당 사항 없음  |  해당 사항 없음  |  이 필드는 RDS for Oracle에 사용되지 않으며 항상 null입니다.  | 
|  `transactionId`  |  string  |  `UNIFIED_AUDIT_TRAIL`의 `TRANSACTION_ID` 열  |  객체가 수정된 트랜잭션의 식별자입니다. 샘플 값은 `02000800D5030000`입니다.  | 

## Amazon RDS for SQL Server에 대한 databaseActivityEventList 필드
<a name="DBActivityStreams.AuditLog.databaseActivityEventList.rss"></a>

Amazon RDS for SQL Server에 대한 `databaseActivityEventList` 필드는 다음과 같습니다.


| 필드 | 데이터 형식 | 소스 | 설명 | 
| --- | --- | --- | --- | 
|  `class`  |  문자열  |  ` sys.fn_get_audit_file.class_type`이 `sys.dm_audit_class_type_map.class_type_desc`에 매핑됨  |  활동 이벤트의 클래스입니다. 자세한 내용은 Microsoft 설명서의 [SQL Server Audit(데이터베이스 엔진)](https://learn.microsoft.com/en-us/sql/relational-databases/security/auditing/sql-server-audit-database-engine?view=sql-server-ver16)를 참조하세요.  | 
|  `clientApplication`  |  문자열  |  `sys.fn_get_audit_file.application_name`  |  클라이언트가 보고한 대로 클라이언트가 연결하는 애플리케이션(SQL Server 버전 14 이상). SQL Server 버전 13에서는 이 필드가 null입니다.  | 
|  `command`  |  문자열  |  `sys.fn_get_audit_file.action_id`이 `sys.dm_audit_actions.name`에 매핑됨  |  SQL 문의 일반 범주입니다. 이 필드의 값은 클래스의 값에 따라 달라집니다.  | 
|  `commandText`  |  문자열  |  `sys.fn_get_audit_file.statement`  |  이 필드는 SQL 문을 나타냅니다.  | 
|  `databaseName`  |  문자열  |  `sys.fn_get_audit_file.database_name`  |  데이터베이스 이름  | 
|  `dbProtocol`  |  문자열  |  해당 사항 없음  |  데이터베이스 프로토콜. 이 값은 `SQLSERVER`입니다.  | 
|  `dbUserName`  |  문자열  |  `sys.fn_get_audit_file.server_principal_name`  |  클라이언트 인증을 위한 데이터베이스 사용자.  | 
|  `endTime`  |  문자열  |  해당 사항 없음  |  이 필드는 Amazon RDS for SQL Server에서 사용되지 않으며 값은 null입니다.  | 
|  `engineNativeAuditFields`  |  객체  |  `sys.fn_get_audit_file`에서 이 열에 나열되지 않은 각 필드.  |  기본적으로 이 객체는 비어 있습니다. `--engine-native-audit-fields-included` 옵션을 사용하여 활동 스트림을 시작하면 이 객체에는 이 JSON 맵에서 반환되지 않는 다른 네이티브 엔진 감사 필드가 포함됩니다.  | 
|  `errorMessage`  |  문자열  |  해당 사항 없음  |  이 필드는 Amazon RDS for SQL Server에서 사용되지 않으며 값은 null입니다.  | 
|  `exitCode`  |  정수  |  `sys.fn_get_audit_file.succeeded`  |  이벤트를 시작한 작업의 성공 여부를 나타냅니다. 이 필드는 null일 수 없습니다. 로그인 이벤트를 제외한 모든 이벤트의 경우 이 필드는 권한 검사의 성공 또는 실패 여부를 보고하지만 작업의 성공 또는 실패 여부는 보고하지 않습니다. 값은 다음과 같습니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/DBActivityStreams.AuditLog.databaseActivityEventList.html)  | 
|  `logTime`  |  문자열  |  `sys.fn_get_audit_file.event_time`  |  SQL Server에서 기록되는 이벤트 타임스탬프입니다.  | 
|  `netProtocol`  |  문자열  |  해당 사항 없음  |  이 필드는 Amazon RDS for SQL Server에서 사용되지 않으며 값은 null입니다.  | 
|  `objectName`  |  문자열  |  `sys.fn_get_audit_file.object_name`  |  SQL 문이 하나의 객체에서 작동하는 경우 데이터베이스 객체의 이름.  | 
|  `objectType`  |  문자열  |  `sys.fn_get_audit_file.class_type`이 `sys.dm_audit_class_type_map.class_type_desc`에 매핑됨  |  SQL 문이 하나의 객체 유형에서 작동하는 경우 데이터베이스 객체의 유형.  | 
|  `paramList`  |  문자열  |  해당 사항 없음  |  이 필드는 Amazon RDS for SQL Server에서 사용되지 않으며 값은 null입니다.  | 
|  `pid`  |  정수  |  N/A  |  이 필드는 Amazon RDS for SQL Server에서 사용되지 않으며 값은 null입니다.  | 
|  `remoteHost`  |  문자열  |  `sys.fn_get_audit_file.client_ip`  |  SQL 문을 실행한 클라이언트의 IP 주소 또는 호스트 이름(SQL Server 버전 14 이상). SQL Server 버전 13에서는 이 필드가 null입니다.  | 
|  `remotePort`  |  정수  |  N/A  |  이 필드는 Amazon RDS for SQL Server에서 사용되지 않으며 값은 null입니다.  | 
|  `rowCount`  |  정수  |  `sys.fn_get_audit_file.affected_rows`  |  SQL 문에 의해 영향을 받는 테이블 행 수(SQL Server 버전 14 이상). 이 필드는 SQL Server 버전 13에 있습니다.  | 
|  `serverHost`  |  문자열  |  데이터베이스 호스트  |  호스트 데이터베이스 서버의 IP 주소.  | 
|  `serverType`  |  문자열  |  해당 사항 없음  |  데이터베이스 서버 유형입니다. 이 값은 `SQLSERVER`입니다.  | 
|  `serverVersion`  |  문자열  |  데이터베이스 호스트  |  데이터베이스 서버 버전(예: SQL Server 2017의 경우 15.00.4073.23.v1.R1)  | 
|  `serviceName`  |  문자열  |  데이터베이스 호스트  |  서비스의 이름입니다. 예시 값은 `sqlserver-ee`입니다.  | 
|  `sessionId`  |  정수  |  `sys.fn_get_audit_file.session_id`  |  세션의 고유 식별자.  | 
|  `startTime`  |  문자열  |  해당 사항 없음  |  이 필드는 Amazon RDS for SQL Server에서 사용되지 않으며 값은 null입니다.  | 
|  `statementId`  |  문자열  |  `sys.fn_get_audit_file.sequence_group_id`  |  클라이언트의 SQL 문에 대한 고유 식별자. 생성되는 이벤트마다 식별자가 다릅니다. 샘플 값은 `0x38eaf4156267184094bb82071aaab644`입니다.  | 
|  `substatementId`  |  정수  |  `sys.fn_get_audit_file.sequence_number`  |  문의 시퀀스 번호를 결정하는 식별자. 이 식별자는 대용량 레코드를 여러 레코드로 분할할 때 유용합니다.  | 
|  `transactionId`  |  정수  |  `sys.fn_get_audit_file.transaction_id`  |  트랜잭션의 식별자. 활성 트랜잭션이 없으면 값은 0입니다.  | 
|  `type`  |  문자열  |  데이터베이스 활동 스트림 생성됨  |  이벤트의 유형입니다. 값은 `record` 또는 `heartbeat`입니다.  | 

# AWS SDK를 사용하여 데이터베이스 활동 스트림 처리
<a name="DBActivityStreams.CodeExample"></a>

AWS SDK를 사용하여 프로그래밍 방식으로 활동 스트림을 처리할 수 ​​있습니다. 다음은 제대로 작동하는 Java 및 Python 예시로, 인스턴스 기반 활성화를 위해 데이터베이스 활동 스트림을 사용하는 방법을 보여줍니다.

------
#### [ Java ]

```
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.GZIPInputStream;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CryptoInputStream;
import com.amazonaws.encryptionsdk.jce.JceMasterKey;
import com.amazonaws.services.kinesis.clientlibrary.exceptions.InvalidStateException;
import com.amazonaws.services.kinesis.clientlibrary.exceptions.ShutdownException;
import com.amazonaws.services.kinesis.clientlibrary.exceptions.ThrottlingException;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessor;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorCheckpointer;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorFactory;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.InitialPositionInStream;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.KinesisClientLibConfiguration;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.ShutdownReason;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker.Builder;
import com.amazonaws.services.kinesis.model.Record;
import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.AWSKMSClientBuilder;
import com.amazonaws.services.kms.model.DecryptRequest;
import com.amazonaws.services.kms.model.DecryptResult;
import com.amazonaws.util.Base64;
import com.amazonaws.util.IOUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class DemoConsumer {

    private static final String STREAM_NAME = "aws-rds-das-[instance-external-resource-id]"; // aws-rds-das-db-ABCD123456
    private static final String APPLICATION_NAME = "AnyApplication"; //unique application name for dynamo table generation that holds kinesis shard tracking
    private static final String AWS_ACCESS_KEY = "[AWS_ACCESS_KEY_TO_ACCESS_KINESIS]";
    private static final String AWS_SECRET_KEY = "[AWS_SECRET_KEY_TO_ACCESS_KINESIS]";
    private static final String RESOURCE_ID = "[external-resource-id]"; // db-ABCD123456
    private static final String REGION_NAME = "[region-name]"; //us-east-1, us-east-2...
    private static final BasicAWSCredentials CREDENTIALS = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
    private static final AWSStaticCredentialsProvider CREDENTIALS_PROVIDER = new AWSStaticCredentialsProvider(CREDENTIALS);

    private static final AwsCrypto CRYPTO = new AwsCrypto();
    private static final AWSKMS KMS = AWSKMSClientBuilder.standard()
            .withRegion(REGION_NAME)
            .withCredentials(CREDENTIALS_PROVIDER).build();

    class Activity {
        String type;
        String version;
        String databaseActivityEvents;
        String key;
    }

    class ActivityEvent {
        @SerializedName("class") String _class;
        String clientApplication;
        String command;
        String commandText;
        String databaseName;
        String dbProtocol;
        String dbUserName;
        String endTime;
        String errorMessage;
        String exitCode;
        String logTime;
        String netProtocol;
        String objectName;
        String objectType;
        List<String> paramList;
        String pid;
        String remoteHost;
        String remotePort;
        String rowCount;
        String serverHost;
        String serverType;
        String serverVersion;
        String serviceName;
        String sessionId;
        String startTime;
        String statementId;
        String substatementId;
        String transactionId;
        String type;
    }

    class ActivityRecords {
        String type;
        String clusterId; // note that clusterId will contain an empty string on RDS Oracle and RDS SQL Server
        String instanceId;
        List<ActivityEvent> databaseActivityEventList;
    }

    static class RecordProcessorFactory implements IRecordProcessorFactory {
        @Override
        public IRecordProcessor createProcessor() {
            return new RecordProcessor();
        }
    }

    static class RecordProcessor implements IRecordProcessor {

        private static final long BACKOFF_TIME_IN_MILLIS = 3000L;
        private static final int PROCESSING_RETRIES_MAX = 10;
        private static final long CHECKPOINT_INTERVAL_MILLIS = 60000L;
        private static final Gson GSON = new GsonBuilder().serializeNulls().create();

        private static final Cipher CIPHER;
        static {
            Security.insertProviderAt(new BouncyCastleProvider(), 1);
            try {
                CIPHER = Cipher.getInstance("AES/GCM/NoPadding", "BC");
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
                throw new ExceptionInInitializerError(e);
            }
        }

        private long nextCheckpointTimeInMillis;

        @Override
        public void initialize(String shardId) {
        }

        @Override
        public void processRecords(final List<Record> records, final IRecordProcessorCheckpointer checkpointer) {
            for (final Record record : records) {
                processSingleBlob(record.getData());
            }

            if (System.currentTimeMillis() > nextCheckpointTimeInMillis) {
                checkpoint(checkpointer);
                nextCheckpointTimeInMillis = System.currentTimeMillis() + CHECKPOINT_INTERVAL_MILLIS;
            }
        }

        @Override
        public void shutdown(IRecordProcessorCheckpointer checkpointer, ShutdownReason reason) {
            if (reason == ShutdownReason.TERMINATE) {
                checkpoint(checkpointer);
            }
        }

        private void processSingleBlob(final ByteBuffer bytes) {
            try {
                // JSON $Activity
                final Activity activity = GSON.fromJson(new String(bytes.array(), StandardCharsets.UTF_8), Activity.class);

                // Base64.Decode
                final byte[] decoded = Base64.decode(activity.databaseActivityEvents);
                final byte[] decodedDataKey = Base64.decode(activity.key);

                Map<String, String> context = new HashMap<>();
                context.put("aws:rds:db-id", RESOURCE_ID);

                // Decrypt
                final DecryptRequest decryptRequest = new DecryptRequest()
                        .withCiphertextBlob(ByteBuffer.wrap(decodedDataKey)).withEncryptionContext(context);
                final DecryptResult decryptResult = KMS.decrypt(decryptRequest);
                final byte[] decrypted = decrypt(decoded, getByteArray(decryptResult.getPlaintext()));

                // GZip Decompress
                final byte[] decompressed = decompress(decrypted);
                // JSON $ActivityRecords
                final ActivityRecords activityRecords = GSON.fromJson(new String(decompressed, StandardCharsets.UTF_8), ActivityRecords.class);

                // Iterate throught $ActivityEvents
                for (final ActivityEvent event : activityRecords.databaseActivityEventList) {
                    System.out.println(GSON.toJson(event));
                }
            } catch (Exception e) {
                // Handle error.
                e.printStackTrace();
            }
        }

        private static byte[] decompress(final byte[] src) throws IOException {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(src);
            GZIPInputStream gzipInputStream = new GZIPInputStream(byteArrayInputStream);
            return IOUtils.toByteArray(gzipInputStream);
        }

        private void checkpoint(IRecordProcessorCheckpointer checkpointer) {
            for (int i = 0; i < PROCESSING_RETRIES_MAX; i++) {
                try {
                    checkpointer.checkpoint();
                    break;
                } catch (ShutdownException se) {
                    // Ignore checkpoint if the processor instance has been shutdown (fail over).
                    System.out.println("Caught shutdown exception, skipping checkpoint." + se);
                    break;
                } catch (ThrottlingException e) {
                    // Backoff and re-attempt checkpoint upon transient failures
                    if (i >= (PROCESSING_RETRIES_MAX - 1)) {
                        System.out.println("Checkpoint failed after " + (i + 1) + "attempts." + e);
                        break;
                    } else {
                        System.out.println("Transient issue when checkpointing - attempt " + (i + 1) + " of " + PROCESSING_RETRIES_MAX + e);
                    }
                } catch (InvalidStateException e) {
                    // This indicates an issue with the DynamoDB table (check for table, provisioned IOPS).
                    System.out.println("Cannot save checkpoint to the DynamoDB table used by the Amazon Kinesis Client Library." + e);
                    break;
                }
                try {
                    Thread.sleep(BACKOFF_TIME_IN_MILLIS);
                } catch (InterruptedException e) {
                    System.out.println("Interrupted sleep" + e);
                }
            }
        }
    }

    private static byte[] decrypt(final byte[] decoded, final byte[] decodedDataKey) throws IOException {
        // Create a JCE master key provider using the random key and an AES-GCM encryption algorithm
        final JceMasterKey masterKey = JceMasterKey.getInstance(new SecretKeySpec(decodedDataKey, "AES"),
                "BC", "DataKey", "AES/GCM/NoPadding");
        try (final CryptoInputStream<JceMasterKey> decryptingStream = CRYPTO.createDecryptingStream(masterKey, new ByteArrayInputStream(decoded));
             final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            IOUtils.copy(decryptingStream, out);
            return out.toByteArray();
        }
    }

    public static void main(String[] args) throws Exception {
        final String workerId = InetAddress.getLocalHost().getCanonicalHostName() + ":" + UUID.randomUUID();
        final KinesisClientLibConfiguration kinesisClientLibConfiguration =
                new KinesisClientLibConfiguration(APPLICATION_NAME, STREAM_NAME, CREDENTIALS_PROVIDER, workerId);
        kinesisClientLibConfiguration.withInitialPositionInStream(InitialPositionInStream.LATEST);
        kinesisClientLibConfiguration.withRegionName(REGION_NAME);
        final Worker worker = new Builder()
                .recordProcessorFactory(new RecordProcessorFactory())
                .config(kinesisClientLibConfiguration)
                .build();

        System.out.printf("Running %s to process stream %s as worker %s...\n", APPLICATION_NAME, STREAM_NAME, workerId);

        try {
            worker.run();
        } catch (Throwable t) {
            System.err.println("Caught throwable while processing data.");
            t.printStackTrace();
            System.exit(1);
        }
        System.exit(0);
    }

    private static byte[] getByteArray(final ByteBuffer b) {
        byte[] byteArray = new byte[b.remaining()];
        b.get(byteArray);
        return byteArray;
    }
}
```

------
#### [ Python ]

```
import base64
import json
import zlib
import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy
from aws_encryption_sdk.internal.crypto import WrappingKey
from aws_encryption_sdk.key_providers.raw import RawMasterKeyProvider
from aws_encryption_sdk.identifiers import WrappingAlgorithm, EncryptionKeyType
import boto3

REGION_NAME = '<region>'                    # us-east-1
RESOURCE_ID = '<external-resource-id>'      # db-ABCD123456
STREAM_NAME = 'aws-rds-das-' + RESOURCE_ID  # aws-rds-das-db-ABCD123456

enc_client = aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)

class MyRawMasterKeyProvider(RawMasterKeyProvider):
    provider_id = "BC"

    def __new__(cls, *args, **kwargs):
        obj = super(RawMasterKeyProvider, cls).__new__(cls)
        return obj

    def __init__(self, plain_key):
        RawMasterKeyProvider.__init__(self)
        self.wrapping_key = WrappingKey(wrapping_algorithm=WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING,
                                        wrapping_key=plain_key, wrapping_key_type=EncryptionKeyType.SYMMETRIC)

    def _get_raw_key(self, key_id):
        return self.wrapping_key


def decrypt_payload(payload, data_key):
    my_key_provider = MyRawMasterKeyProvider(data_key)
    my_key_provider.add_master_key("DataKey")
    decrypted_plaintext, header = enc_client.decrypt(
        source=payload,
        materials_manager=aws_encryption_sdk.materials_managers.default.DefaultCryptoMaterialsManager(master_key_provider=my_key_provider))
    return decrypted_plaintext


def decrypt_decompress(payload, key):
    decrypted = decrypt_payload(payload, key)
    return zlib.decompress(decrypted, zlib.MAX_WBITS + 16)


def main():
    session = boto3.session.Session()
    kms = session.client('kms', region_name=REGION_NAME)
    kinesis = session.client('kinesis', region_name=REGION_NAME)

    response = kinesis.describe_stream(StreamName=STREAM_NAME)
    shard_iters = []
    for shard in response['StreamDescription']['Shards']:
        shard_iter_response = kinesis.get_shard_iterator(StreamName=STREAM_NAME, ShardId=shard['ShardId'],
                                                         ShardIteratorType='LATEST')
        shard_iters.append(shard_iter_response['ShardIterator'])

    while len(shard_iters) > 0:
        next_shard_iters = []
        for shard_iter in shard_iters:
            response = kinesis.get_records(ShardIterator=shard_iter, Limit=10000)
            for record in response['Records']:
                record_data = record['Data']
                record_data = json.loads(record_data)
                payload_decoded = base64.b64decode(record_data['databaseActivityEvents'])
                data_key_decoded = base64.b64decode(record_data['key'])
                data_key_decrypt_result = kms.decrypt(CiphertextBlob=data_key_decoded,
                                                      EncryptionContext={'aws:rds:db-id': RESOURCE_ID})
                print (decrypt_decompress(payload_decoded, data_key_decrypt_result['Plaintext']))
            if 'NextShardIterator' in response:
                next_shard_iters.append(response['NextShardIterator'])
        shard_iters = next_shard_iters


if __name__ == '__main__':
    main()
```

------

# 데이터베이스 활동 스트림의 IAM 정책 예제
<a name="DBActivityStreams.ManagingAccess"></a>

데이터베이스 활동 스트림에 대한 적절한 AWS Identity and Access Management(IAM) 역할 권한이 있는 사용자는 DB인스턴스에 대한 활동 스트림 설정을 작성, 시작, 중지하고 수정할 수 있습니다. 이러한 작업은 스트림의 감사 로그에 포함됩니다. 규정을 준수하는 최선의 방법은 DBA에 이러한 권한을 제공하지 않는 것입니다.

IAM 정책을 사용하여 데이터베이스 활동 스트림에 대한 액세스를 설정합니다. Amazon RDS 인증에 대한 자세한 내용은 [Amazon RDS의 자격 증명 및 액세스 관리](UsingWithRDS.IAM.md) 섹션을 참조하세요. IAM 정책 생성에 대한 자세한 내용은 [IAM 데이터베이스 액세스를 위한 IAM 정책 생성 및 사용](UsingWithRDS.IAMDBAuth.IAMPolicy.md) 단원을 참조하십시오.

**Example 데이터베이스 활동 스트림 구성을 허용하는 정책**  
사용자에게 활동 스트림을 수정할 수 있는 세분화된 액세스를 제공하려면 IAM 정책에서 서비스별 작업 컨텍스트 키 `rds:StartActivityStream` 및 `rds:StopActivityStream`을 사용하세요. 다음 IAM 정책 예제는 사용자 또는 역할이 활동 스트림을 구성할 수 있도록 허용합니다.    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "ConfigureActivityStreams",
            "Effect": "Allow",
            "Action": [
                "rds:StartActivityStream",
                "rds:StopActivityStream"
            ],
            "Resource": "*"
        }
    ]
}
```

**Example 데이터베이스 활동 스트림 시작을 허용하는 정책**  
다음 IAM 정책 예제는 사용자 또는 역할이 활동 스트림을 시작할 수 있도록 허용합니다.    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement":[
        {
            "Sid":"AllowStartActivityStreams",
            "Effect":"Allow",
            "Action":"rds:StartActivityStream",
            "Resource":"*"
        }
    ]
}
```

**Example 데이터베이스 활동 스트림 중지를 허용하는 정책**  
다음 IAM 정책 예제는 사용자 또는 역할이 활동 스트림을 중지할 수 있도록 허용합니다.    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement":[
        {
            "Sid":"AllowStopActivityStreams",
            "Effect":"Allow",
            "Action":"rds:StopActivityStream",
            "Resource":"*"
        }
     ]
}
```

**Example 데이터베이스 활동 스트림 시작을 거부하는 정책**  
다음 IAM 정책 예제는 사용자 또는 역할이 활동 스트림을 시작하지 못하게 합니다.    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement":[
        {
            "Sid":"DenyStartActivityStreams",
            "Effect":"Deny",
            "Action":"rds:StartActivityStream",
            "Resource":"*"
        }
     ]
}
```

**Example 데이터베이스 활동 스트림 중지를 거부하는 정책**  
다음 IAM 정책 예제는 사용자 또는 역할이 활동 스트림을 중지하지 못하게 합니다.    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement":[
        {
            "Sid":"DenyStopActivityStreams",
            "Effect":"Deny",
            "Action":"rds:StopActivityStream",
            "Resource":"*"
        }
    ]
}
```