CloudWatch Logs 보존기간 정하기: 92개 로그 그룹 점검
CloudWatch 로그 그룹 92개의 용도와 규정상 필요 기간을 확인하고, 무기한 보관을 유한한 보존정책으로 바꾼 기준과 검증 방법을 설명한다.
이 글의 목차기간보다 먼저 쓰임을 나눴다5
CloudWatch Logs를 점검했을 때 로그 그룹이 92개였다.
로그 그룹은 한 서비스나 기능에서 나온 실행 기록을 묶어 권한과 보관 방식을 관리하는 단위다.
일부는 보존기간이 없었다.
CloudWatch에서 보존기간을 지정하지 않으면 콘솔에 Never Expire라고 표시되고 로그가 계속 남는다.
당장 장애를 만들지는 않지만, 그룹이 쌓일수록 비용과 보관 책임을 설명하기 어려워진다.
기간보다 먼저 쓰임을 나눴다
처음에는 모든 그룹에 넉넉한 기간 하나를 넣으면 간단하다고 생각했다.
숫자만 통일하면 “왜 이 로그를 그만큼 보관하는가”라는 질문은 그대로 남았다.
장애가 났을 때 과거 상태를 되짚는 로그인지, 보안 감사에 필요한 기록인지, 배포 직후에만 가치가 큰 디버깅 로그인지부터 나눴다.
회사 정책이 정한 최소 기간과 현재 서비스의 소유자도 함께 확인했다.
민감한 값이 들어갈 가능성이 있다면 오래 보관하는 방법보다 애초에 기록하지 않는 방법을 먼저 검토했다.
예를 들어 사용자 요청의 오류 로그는 최근 장애를 재현할 기간이 중요하고, 관리자 로그인 감사 로그는 보안 정책이 요구하는 기간이 우선이다.
개발 브랜치의 상세 디버깅 로그는 며칠 뒤 가치가 크게 줄 수 있다.
다음 표의 기간은 그대로 복사할 정책이 아니라 분류 질문을 보여 주는 예시다.
| 로그 종류 | 먼저 물어볼 질문 | 보존 결정의 기준 |
|---|---|---|
| 애플리케이션 오류 | 가장 늦게 발견되는 장애는 며칠 뒤인가 | 장애 탐지·재현에 필요한 기간 |
| 인증·관리자 활동 | 감사나 사고 조사에서 요구하는 최소 기간은 얼마인가 | 회사 정책과 법적 의무 |
| 배포·개발 디버깅 | 어느 배포 이후에는 다시 볼 가치가 사라지는가 | 짧은 운영 필요 기간 |
| 장기 분석용 원본 | CloudWatch에서 즉시 검색해야 하는가 | S3 같은 별도 보관소와 복구 방법 |
정책으로 기간이 정해진 11개는 90일로 맞췄다.
나머지는 각 로그의 운영 목적에 맞는 유한한 기간을 적용했다.
목록을 한 번에 꺼내 기준점을 만들었다
콘솔에서 92개를 하나씩 열기보다 AWS CLI로 현재 상태를 조회했다.
retentionInDays는 보존 일수다.
값이 비어 있으면 무기한 보관 상태다.
storedBytes는 현재 저장된 로그의 크기를 바이트 단위로 보여 준다.
여기서 92개는 명령을 실행한 AWS 계정과 리전에서 조회한 수다.
CloudWatch Logs는 리전 단위 서비스라 한 리전의 결과를 회사 계정 전체로 해석하면 안 된다.
같은 점검을 반복하려면 먼저 aws sts get-caller-identity로 계정 ID를 확인하고, CLI가 사용할 자격 증명 묶음인 profile과 작업 지역을 고르는 --region 값을 변경 기록에 함께 남겨야 한다.
여러 계정이나 리전을 운영한다면 각 조합을 따로 조회한다.
aws logs describe-log-groups \
--query "logGroups[].{name:logGroupName,retention:retentionInDays,bytes:storedBytes}" \
--output tabledescribe-log-groups는 설정을 바꾸지 않는다.
--query로 이름·보존기간·저장량만 골랐고, --output table로 변경 전 목록을 비교하기 쉽게 만들었다.
저장량이 큰 순서만 보고 기간을 정하지는 않았다.
크기가 작은 감사 로그가 큰 디버깅 로그보다 오래 필요할 수 있다.
이 목록의 역할은 정답을 정하는 것이 아니라 누락을 찾고 변경 전후의 전체 개수를 맞추는 것이었다.
만료될 로그를 확인한 뒤 기간을 바꿨다
보존기간을 짧게 바꾸면 새 기준보다 오래된 이벤트가 삭제 대상이 된다.
실제 삭제가 끝난 기록은 기간을 다시 늘려도 복구할 수 없다.
실행 전에는 대상 그룹, 감사·사고 조사에 필요한 최소 기간, 별도 보관이 필요한 로그를 확인해야 한다.
별도 보관이 필요한 로그는 보존기간부터 줄이면 안 된다.
일회성 보관이라면 CloudWatch 로그를 객체 저장소인 S3로 옮기는 export task가 COMPLETED인지 보고 대상 기간의 객체가 실제 버킷에 있는지 확인한다.
계속 보관해야 하는 로그라면 매번 export를 만드는 대신 새 로그를 다른 저장소로 전달하는 subscription을 구성하는 편이 더 적합하다.
완료 상태나 복구 가능성을 확인하지 않은 export 계획은 백업으로 보지 않았다.
보존기간과 백업은 목적도 다르다.
보존기간은 CloudWatch에서 검색할 수 있는 로그의 나이를 제한하고, 백업은 원본이 사라져도 별도 위치에서 복구할 수 있게 만든다.
기간을 90일로 지정했다는 사실만으로 백업이 생기지는 않는다.
변경 목록에는 계정·리전, 로그 그룹 이름, 소유자, 기존 기간, 새 기간, 변경 이유와 별도 보관 여부를 적는다.
put-retention-policy에는 보존 변경을 미리 시뮬레이션하는 dry-run이 없으므로 처음부터 전부 바꾸지 않고 소량을 적용해 재조회한 뒤 나머지를 진행하는 편이 안전하다.
아래는 정책 대상에 90일을 적용한 명령 형식이다.
실제 로그 그룹 이름은 제외했다.
aws logs put-retention-policy \
--log-group-name "<log-group-name>" \
--retention-in-days 90--log-group-name은 변경할 그룹을 고르고, --retention-in-days 90은 90일보다 오래된 이벤트를 만료 대상으로 만든다.
대상 이름과 기간을 다시 읽은 뒤 실행했다.
보존 일수에는 아무 정수나 넣을 수 없다.
1, 3, 5, 7, 14, 30, 60, 90일처럼 AWS가 허용한 고정값에서 골라야 한다.
명령이 받아들이는 최신 목록은 put-retention-policy 문서에서 확인한다.
적용 후 처음과 같은 조회를 반복했다.
작업 범위였던 92개 모두에 유한한 보존기간이 있었고, Never Expire는 0개였다.
정책 대상 11개도 모두 90일이었다.
90일은 이 11개에 적용한 기준이며 나머지 81개까지 같은 기간으로 통일한 작업은 아니다.
눈으로 표를 세는 대신 아래처럼 무기한 그룹 수를 다시 셀 수 있다.
결과가 0이어야 이번 작업의 완료 조건과 맞는다.
정책 대상 11개는 별도로 만든 변경 목록과 실제 retentionInDays를 대조했다.
aws logs describe-log-groups \
--query 'length(logGroups[?retentionInDays==`null`])' \
--output textCloudWatch는 보존기간을 넘긴 이벤트를 즉시 물리 삭제하지 않는다.
AWS 문서에 따르면 보통 최대 72시간이 걸리고 드물게 더 오래 걸릴 수 있다.
삭제 대상으로 표시된 이벤트는 그동안 장기 보관 스토리지 요금과 API의 storedBytes 계산에서 제외된다.
콘솔에서 사라지는 시점과 과금에 반영되는 시점을 따로 본 이유다.
이 지연은 기간을 다시 늘릴 때도 중요하다.
보존기간을 줄인 직후 마음을 바꿔 늘리면 아직 물리 삭제되지 않은 오래된 이벤트가 예상과 다르게 남을 수 있다.
AWS 안내대로 이전 기준을 넘은 이벤트가 삭제됐음을 확인하거나 최대 72시간을 기다린 뒤 기간을 늘려야 한다.
무기한 보관을 없애고 비용 추정의 기준을 만들었다
이번 작업에서 해결한 문제는 “언제까지 남는지 모르는 로그”였다.
점검 대상 92개 모두에 유한한 보존기간을 넣었고 Never Expire는 0개가 됐다.
그중 정책 대상 11개는 90일로 맞췄다.
이 작업의 직접 결과는 청구 금액이 아니라 보관 책임의 상한을 만든 것이다.
만료 기준 없이 과거 로그가 계속 누적되던 구조는 끝났다.
절감 규모는 각 그룹의 일평균 로그 유입량을 알면 조건부로 추정할 수 있다.
초기 저장량을 제외하고 유입량이 일정하다고 가정하면, 하루 평균 rGiB가 쌓이는 그룹을 무기한에서 D일 보관으로 바꾼 뒤 T일 시점의 보관 대상 차이는 계산상 약 r × (T - D)GiB다(T > D).
예를 들어 하루 1GiB가 계속 들어오는 그룹을 90일로 바꾸면 180일 시점에는 무기한 보관보다 약 90GiB가 적다.
실제 청구액은 리전, 로그 클래스, 유입량 변화와 AWS의 과금 기준에 따라 달라지므로 이 값은 비용이 아니라 보관량 추정치다.
이 방식은 장애 분석과 감사에 필요한 최소 기간을 정할 수 있고, 그 이후의 원본 로그가 필요하지 않을 때 쓴다.
규정상 장기 보관이 필요하면 기간부터 줄이지 않고 별도 보관 경로와 복구 가능성을 먼저 확인해야 한다.
이번처럼 한 번 정리하는 데서 끝내지 않으려면 새 로그 그룹의 보존기간을 인프라 코드에 넣고, retentionInDays가 비어 있는 그룹을 정기 점검 대상으로 만드는 것이 마무리다.