로그로 원인 찾기 · 큰 파일에서 필요한 구간만 · 실습
사고 구간 3분을 보려다 하루치를 통째로 읽었다
목표
회전까지 끝난 여섯 시간치 로그에서 사고 구간 3분만 꺼냅니다. 겹치지 않는 파일은 열지 않고, 남은 파일에서는 이진 탐색으로 바이트 구간을 찍어 그 사이만 읽고, 압축본은 앞에서부터 훑되 일찍 멈춥니다.
왜 중요한가
"3분만 보여 달라" 는 요청에 하루치를 통째로 읽는 것이 로그 작업에서 가장 흔한 사고입니다. 그런데 시각이 RFC 3339 표기로 굳어 있고 파일이 시간순이면 문자열 비교가 곧 시간 비교라, 파일을 읽지 않고 이진 탐색으로 구간의 시작 자리를 찍을 수 있습니다. 어려운 것은 탐색이 아니라 경계입니다. 구간을 반열림으로 잡아야 이어지는 구간이 겹치지 않고, 같은 시각의 줄이 여럿일 때 그 시각의 첫 줄을 찾아야 앞의 몇 줄이 조용히 빠지지 않습니다. 그리고 빠르다는 말만으로는 아무것도 증명되지 않으므로, 통째로 훑는 느린 방법과 한 번은 대조해야 합니다.
단계
1. /root/slice/gen_slice.py 를 만들어 실행해 /root/slice/var/log/ 아래 app.log · app.log.1 · app.log.2.gz 를 만드세요.
2. /root/slice/index.json — 회전본을 오래된 것부터 세우고 파일마다 담긴 구간을 적으세요.
3. /root/slice/plan.json — 사고 구간과 겹치는 파일만 고르고 나머지는 이유와 함께 건너뛰세요.
4. /root/slice/offsets.json — 이진 탐색으로 구간의 시작 바이트와 끝 바이트를 찍으세요.
5. /root/slice/window_a.log — 찍어 둔 바이트 구간만 읽어 사고 구간을 뽑으세요.
6. /root/slice/proof.json — 느린 방법과 대조해 결과가 같음을 증명하세요.
7. /root/slice/window_b.log 와 /root/slice/gz_scan.json — 압축본 안의 두 번째 구간을 일찍 멈추며 뽑으세요.
8. /root/slice/slice_report.md — 방법과 근거를 보고서로 남기세요.
참고
- 사고 구간은
2026-04-12T03:58:30.000Z부터2026-04-12T04:01:30.000Z까지이고, 두 번째 구간은2026-04-12T00:20:00.000Z부터2026-04-12T00:23:00.000Z까지입니다. 둘 다 시작은 포함하고 끝은 포함하지 않는 반열림 구간입니다. - 줄의 앞 24자가 시각입니다. 표기가 통일되어 있으므로
line[:24] >= key같은 문자열 비교가 그대로 시간 비교입니다. - 이진 탐색에서
seek한 자리는 거의 늘 줄 한가운데입니다. 한 줄을 읽어 버려 줄 경계에 선 다음 판정하세요. - 흔한 실수: 같은 시각의 줄 가운데 첫 줄이 아닌 것을 찾기, 끝 시각의 줄까지 넣기, 회전 경계 너머의 파일을 빼먹기, 압축본에 이진 탐색을 걸기.
- 현장의 파일은 수 GB 이지만 이 실습은 같은 구조를 20MB 로 줄여 재현합니다. 산출물은 전부
/root/slice/아래에 모이고, 세션이 끝나면 사라집니다.
단계 8개
- 회전까지 끝난 로그 묶음 재현하기
- 회전본을 시간순으로 세우고 담긴 구간 재기
- 겹치지 않는 파일은 아예 열지 않기
- 이진 탐색으로 구간의 시작과 끝을 바이트로 찍기
- 찍어 둔 바이트 구간만 읽어 사고 구간 뽑기
- 느린 방법과 대조해 결과를 증명하기
- 압축본에서는 일찍 멈추는 것이 답이다
- 방법과 근거를 문서로 남기기