로그로 원인 찾기 · 보존과 회전을 숫자로 정한다 · 실습
사고가 난 날의 로그는 이미 지워져 있었다
목표
회전된 로그 묶음에서 실제 보관 구간을 재고, 사고 구간이 그 범위 밖임을 숫자로 밝히고, 압축률을 실측해 보존 일수와 용량을 계산해 회전 정책으로 적습니다. 마지막으로 속도 제한에 걸려 애초에 기록되지 않는 줄을 셉니다.
왜 중요한가
조사 첫날 가장 자주 만나는 벽은 어려운 질문이 아니라 빈 디렉터리입니다. 그때 필요한 것은 한탄이 아니라 세 개의 숫자입니다 — 며칠이 모자랐는가, 얼마를 더 남겨야 하는가, 그 값이 디스크 예산에 맞는가. 세 숫자는 전부 지금 있는 파일에서 잴 수 있습니다. 그리고 "로그가 없다" 는 두 가지 뜻입니다. 회전으로 지워졌거나, 속도 제한에 걸려 애초에 기록되지 않았거나. 대책이 완전히 다르므로 둘을 가려야 합니다.
단계
1. /root/keep/gen_keep.py 를 만들어 실행해 /root/keep/var/log/ 아래 보관 상태를 재현하세요.
2. /root/keep/order.json 에 회전본을 오래된 것부터 세운 목록과 그 규칙을 적으세요.
3. /root/keep/coverage.json 에 파일마다 줄 수와 첫 줄 · 마지막 줄의 시각을 적으세요.
4. /root/keep/window.json 에 사고 구간이 보관 범위 안인지, 얼마나 모자랐는지 적으세요.
5. /root/keep/budget.json 에 압축률 실측값과 보존 일수 · 용량 계산을 적으세요.
6. /root/keep/logrotate.conf 에 회전 정책을 적으세요. rotate 값은 5단계의 계산과 같아야 합니다.
7. /root/keep/ratelimit.json 에 속도 제한에 걸려 버려질 줄 수를 세어 적으세요.
8. /root/keep/keep_report.md 에 네 절로 보고서를 남기세요.
참고
- 이 실습이 주는 가정입니다. 사고 구간은
2026-04-05T02:10:00Z부터2026-04-05T02:40:00Z까지입니다. 운영 서버는 이 표본의 1200배를 찍습니다./var/log의 디스크 예산은 4 GiB(4294967296 바이트), 요구 보존 기간은 30일, journald 설정은RateLimitIntervalSec=30·RateLimitBurst=200이고 여유 공간에 따른 배수는 1로 봅니다. - 5단계의 계산 규칙입니다.
sample_raw_bytes_per_day는payments.log.1의 크기,sample_gz_bytes_per_day는payments.log.2.gz의 크기입니다.compression_ratio는 둘의 비를 소수 넷째 자리까지 반올림합니다.delaycompress때문에 최근 두 날은 압축되지 않은 것으로 봅니다.required_bytes_for_30_days는 원본 두 날 + 압축 28일,max_days_in_budget은 예산에서 원본 두 날을 뺀 뒤 압축 하루치로 나눈 몫에 2를 더한 값입니다.rotate_value는 30일치를 남길 때 logrotate 에 적을 숫자입니다. zcat과zgrep으로 압축본을 풀지 않고 읽을 수 있고, 파이썬에서는gzip.open(path, "rt")입니다.- 흔한 실수:
rotate를 보존 일수와 같게 적기, 번호 이름과 날짜 이름을 같은 방향으로 정렬하기, 압축률을 어림으로 넣기, 최근 두 날을 압축본 크기로 계산하기. - 산출물은 전부
/root/keep/아래에 모읍니다. 세션이 끝나면 사라집니다.
단계 8개
- 고객사의 보관 상태 재현하기
- 회전본을 오래된 것부터 세우기
- 파일마다 실제로 담긴 구간 재기
- 사고 구간이 범위 밖임을 숫자로 밝히기
- 압축률을 실측해 보존 일수 계산하기
- 계산한 값으로 회전 정책 적기
- 애초에 기록되지 않는 줄 세기
- 무엇을 바꿀지 글로 남기기