CloudWatch에 저장하는 로그의 비용 줄이기

CloudWatch Logs에 저장된 로그를 비용 효율적으로 보관하는 방법에 대하여 작성한 글입니다
2023.11.17

안녕하세요 클래스메소드의 수재입니다.
보통 AWS를 운용할 때 로그를 저장하고 활용하기 위해서 Cloudwatch를 많이 사용합니다.
하지만 CloudWatch에 로그를 저장하기에는 다른 스토리지 서비스에 비해 많은 비용이 발생합니다.
그래서 가능하다면 장기간 저장이 필요한 로그를 S3에 저장한다면 비용이 절약될 수도 있습니다.
이번에는 CloudWatch에 저장된 로그가 일정 기간이 지나면 S3로 이동되도록 하여 AWS의 비용을 줄이는 방법에 대하여 알아보겠습니다.

CloudWatch와 S3의 비교

단순히 저장을 위해서는 스토리지 서비스인 S3를 이용하고, 로그를 다양한 방향으로 활용하기 위해서는 CloudWatch를 이용하는 것이 비용적으로나 기능적으로 바람직하다고 보여집니다.

비용

S3가 스토리지 서비스로 이용되는 만큼 단순히 로그를 저장하는 용도라면 S3를 사용하는 편이 더 저렴합니다.
(서울 리전 기준)

서비스 비용 비고
S3 Standard USD 0.025/GB 처음 50TB 까지
CloudWatch USD 0.0314/GB 저장(아카이브)기능만

게다가 장기간 보관만 하고 액세스를 자주하지 않는 경우에는 S3 One Zone이나 Glacier에 저장하여 더욱 저렴한 비용으로 데이터를 보관할 수 있습니다.

기능 비교

S3만 이용하여 S3에 저장된 로그를 활용하는 것은 힘듭니다.
S3에 저장된 로그를 검색하기 위해서는 AWS Athena를 사용하면 구현할 수 있지만 쿼리의 속도나 추가 비용 발생 등의 문제도 발생합니다.
Athena를 사용하여 Amazon S3 서버 액세스 로그를 분석하려면 어떻게 해야 하나요?

CloudWatch는 기본적으로 로그와 지표의 수집 및 활용을 위해 사용하는 서비스이므로 CloudWatch만을 이용하여 로그를 다양한 방향으로 활용할 수 있습니다.
CloudWatch Logs Insights를 사용하면 Amazon CloudWatch Logs 내 로그 데이터를 대화식으로 검색해 분석할 수 있습니다.
또한 로그 그룹에 저장된 로그를 필터링하거나 필터링 된 로그와 지표를 연관지어 경보를 발생하는 기준으로 사용하는 것도 가능합니다.
Amazon CloudWatch의 기능

로그 저장 비용을 절약하기

결론적으로 로그를 자주 활용하게 되는 기간까지는 CloudWatch에 저장하고 그 이후에는 S3에 저장하여 비용을 절약하는 것이 좋다고 생각됩니다.
로그 저장 비용을 절약하기 위해서는 다음 과정으로 작업을 진행합니다.

  • CloudWatch와 S3에서 로그를 보존할 기간 검토
  • 로그 이동 작업 구현
  • 로그 그룹의 보존 기간 설정
  • S3의 수명 주기 설정(옵션)

우선 현재의 상황에 맞게 CloudWatch에서 S3로 로그의 이동이 필요한지를 검토합니다.
나누어 보존하는 것으로 결정되었다면 각 서비스에서 보존할 기간을 정의합니다.

기간 검토가 완료되었다면 이동 방법에 대해 검토하고 구현합니다.
이를 구현할 수 있는 대표적인 방법으로 다음이 있다고 생각합니다.

  • CloudWatch의 내보내기(Export) 기능 이용
  • AWS Lambda를 이용하여 내보내기
  • Kinesis Data Firehose를 이용하여 내보내기

각각 고려해야할 점이 다르므로 상황에 맞는 방법을 도입하는 것이 좋습니다.
각 방법의 상세한 내용은 아래에서 알아보겠습니다.

이동 작업을 구현하였다면 CloudWatch 로그 그룹의 보존 기간을 변경합니다.
CloudWatch Logs에서 로그 데이터 보존 기간 변경

필요에 따라 일정 기간이 지난 로그를 S3 Standard 에서 S3 One Zone이나 Glacier 로 이동할 필요가 있다면 S3의 수명 주기를 설정합니다.
S3 One Zone이나 Glacier 로 이동하면 로그 보존에 발생하는 비용을 줄일 수 있습니다.
버킷에서 수명 주기 구성 설정

CloudWatch의 내보내기(Export) 기능 이용

CloudWatch에는 로그 그룹을 대상으로 하여 S3로 내보내는 기능이 있습니다.
해당 기능을 이용하기 위해서는 다음 IAM 권한이 필요합니다.

  • logs:CreateExportTask
  • logs:CancelExportTask
  • logs:DescribeExportTasks
  • logs:DescribeLogStreams
  • logs:DescribeLogGroups

콘솔에서 해당 기능을 이용하여 수동으로 S3에 저장할 수도 있지만 EventBridge를 이용하여 이를 자동화 할 수 있습니다.

Evnet Bridge를 이용한 자동화 설정 방법

우선 전제는 다음과 같습니다.

  • CloudWatch에 저장하는 로그의 보존 기간은 30일
  • 내보내기의 주기는 보존 기간 - 1일. 즉, 29일

S3 버킷 생성
로그를 저장할 버킷을 생성하고 다음 정책을 추가합니다.
공식 문서3단계: S3 버킷에 대한 권한 설정 를 참고하여 정책을 설정해주세요.

EventBridge에 연결할 IAM 정책 및 역할 생성
위에서 설명한 필요한 권한이 포함된 IAM 정책(Policies)를 생성합니다.
이어서 IAM 역할(Roles)을 생성합니다. 역할을 생성할 때는 사용자 지정 신뢰 정책(Custom trust policy)을 선택하여 다음 신뢰 정책을 추가합니다.
그리고 생성한 정책과 AmazonS3ReadOnlyAccess 정책을 포함합니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "scheduler.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

EventBridge 생성
정기적으로 동작하도록 스케줄링하기 위해 EventBridge를 생성합니다.
EventBridge의 일정(Schedules)에서 생성할 수 있습니다.

일정 규칙은 전제대로 29일으로 지정하며 유연한 기간(flexible retention)은 꺼짐(off)으로 설정합니다.
타겟은 모든 API > CloudWatch Logs > CreateExportTask 를 선택합니다.
그리고 목표 로그 그룹과 버킷을 특정하기 위해 다음 json을 추가합니다.
Destination, LogGroupName은 적절한 값으로 변환하여 설정합니다.
From과 To는 Unixtime로 계산하여 2023년 1월 1일 0시~2123년 1월 1일 0시가 범위로 지정되어 있습니다.참고

{
  "Destination": "{bucket name}",
  "DestinationPrefix": "<aws.scheduler.scheduled-time>",
  "From": 1672498800000,
  "LogGroupName": "{export log group name}",
  "To": 4828172400000
}

이후 DLQ, 암호화 등을 필요에 따라 설정하고 실행 역할은 방금 생성한 역할을 지정하여 생성합니다.

제대로 설정되어 있다면 버킷에 로그가 저장되는 것을 확인할 수 있습니다.

고려 사항

로그 보존 기간과 내보내기의 기간을 알맞게 조절해야합니다.
예를 들어 매월 1일에 내보내기를 실행하도록 설정하면 CloudWatch 로그 보존 기간이 30일 밖에 선택할 수 없기 때문에 31일이 있는 달의 로그가 1일 누락됩니다.
반대로 로그를 60일 동안 저장하는데 매월 1일에 내보내기를 실행하도록 설정하면 누락은 발생하지 않지만 약 1개월 정도의 로그가 중복되어 저장됩니다.

그리고 내보내기로 S3 버킷에 로그를 저장하는 경우 버킷의 prefix까지는 지원이 가능하지만 그 뒤의 세세한 지정은 할 수 없습니다.
예를 들어 Kinesis Firehose를 이용한 로그 이동은 연/월/일 으로 prefix가 나뉘어 저장되지만 CloudWatch의 로그 내보내기 기능은 그 정도로 세세하게 관리하지는 않습니다.

AWS Lambda를 이용하여 내보내기

Lambda를 사용하여 주기적으로 로그를 불러 S3에 저장할 수도 있습니다.

Lambda를 이용한 설정 방법

위에서 EventBridge를 이용하여 일정한 기간마다 로그 내보내기를 실행한 것 처럼 Lambda를 이용한 방법도 기본적으로 EventBridge를 이용하여 정해진 스케줄에 Lambda를 실행시키는 방식입니다.
목적에 따라 코드는 달라지므로 코드 작성에 참고가 될 만한 글을 소개합니다.

두 글 모두 하루단위로 로그를 이동하도록 작성되어있는 코드이지만 from_date, end_date 등의 파라미터와 EventBridge의 실행 날짜를 수정하여 원하는 기간마다 실행하도록 변경할 수 있습니다.

고려 사항

Lambda로 로그를 이동하지만 이용하는 API가 비동기 동작인 create export를 이용하므로 로그 양에 따라 타임 오버가 발생하여 람다가 에러가 발생할 가능성이 있습니다.
또한 실행하는 텀이 길수록 당연히 로그의 양도 증가하므로 이 또한 람다의 동작 시간 리미트를 변경할 필요가 있습니다.

직접 코드를 작성하는 방법이기 때문에 버킷의 prefix나 이동하는 기간 등 다른 방법보다 자유로운 설정이 가능합니다.

반면 코드를 직접 작성해야한다는 점과 코드의 내용에 따라 유지보수가 필요할 수도 있습니다.
또한 Lambda를 이용하므로 내보내기 기능만 이용하는 것보다 많은 비용이 발생할 수 있습니다.

Kinesis Firehose를 이용한 방법

Kinesis의 구독 필터 기능을 사용하여 CloudWatch logs의 데이터를 손실 없이 S3로 스트리밍하는 방법입니다.
설정 방법은 공식 문서가 준비되어 있습니다.

고려 사항

Kinesis Firehose가 데이터 스트리밍을 목적으로하는 서비스이기 때문에 한달에 한번씩 실행하는 것이 목적이라면 위의 다른 두가지 방법이 더 좋다고 생각합니다.

관리형 서비스이기 때문에 Lambda보다는 적용하기 쉽습니다.
하지만 단순 비용으로 따지면 Lambda보다 조금 더 비싸기 때문에 코드를 작성할 수 있다면 Lambda를 이용하는 것이 좋다고 생각됩니다.

그 외의 트러블 슈팅 등은 다음 문서를 참고해주세요.

마무리

이상으로 비용을 아끼기 위해 CloudWatch Logs에 저장된 로그를 이동하는 방법에 대하여 알아보았습니다.
[로그 저장 비용을 절약하기] 문단에서 설명했듯이 로그의 이동 뿐만 아니라 로그에 대한 접근 빈도를 고려하여 S3의 스토리지 타입 변경도 겸한다면 더욱 비용 효율적인 이용이 가능합니다.

긴 글 읽어주셔서 감사합니다.
오탈자 및 내용 피드백은 must01940 지메일로 보내주시면 감사합니다.