로그로 원인 찾기 · 집계와 상관관계 · 실습
흩어진 로그를 인과로 묶기
목표
서로 다른 형식의 로그 세 개를 겹쳐, 흩어진 사실들을 하나의 인과로 묶을 수 있게 됩니다.
왜 중요한가
에러 로그부터 보는 것은 자연스럽지만 이야기의 중간부터 읽는 것입니다. 전형적인 열화는 변경 → 일부 요청 지연(경고) → 자원 점유 → 타임아웃(에러) → 알람 순으로 진행되고, 에러 로그만 보면 마지막 두 단계만 보입니다. 그래서 던져야 할 질문은 "언제 에러가 시작됐나" 가 아니라 "언제 정상이 아니게 됐나" 이고, 경고 레벨의 첫 등장 시각이 그 답입니다.
이 실습에서 확인하게 될 또 하나는 평균의 무력함입니다. 전체 평균 지연은 어떤 요청도 대표하지 못하지만, "1000ms 를 넘는 요청이 몇 건인가" 는 즉시 문제를 드러냅니다. 지표를 하나만 뽑아야 한다면 평균이 아니라 임계 초과 건수를 뽑으세요.
로그 세 개
/opt/data/app.jsonl— 한 줄이 하나의 JSON.ts,level,service,request_id,path,status,latency_ms,msg/opt/data/db-slow.log—ts=<epoch> duration_ms=<n> table=<name> query="..."/opt/data/deploy.log— 배포와 롤백 이력
단계
1. /root/correlate 디렉터리를 만드세요.
2. app.jsonl 에서 level 이 error 인 줄의 개수를 /root/correlate/error_count.txt 에 적으세요.
3. 에러 메시지가 지목하는 테이블 이름을 /root/correlate/table.txt 에 적으세요.
4. 전체 latency_ms 의 평균을 정수로 내림해 /root/correlate/avg_latency.txt 에 적으세요.
5. latency_ms 가 1000 을 초과하는 요청 수를 /root/correlate/slow_count.txt 에 적으세요.
6. level 이 warn 인 가장 이른 줄의 시각을 HH:MM 으로 /root/correlate/first_warn.txt 에 적으세요.
7. deploy.log 에서 사고 직전에 배포된 payment 서비스 버전을 /root/correlate/version.txt 에 적으세요.
8. /root/correlate/link.md 에 인과를 정리하세요. 배포 버전, 느려진 테이블, 최초 경고 시각, 에러 시각이 모두 들어가야 합니다.
참고
grep '"level": "error"' /opt/data/app.jsonl | wc -l- python3 한 줄로 파싱하는 편이 편할 수 있습니다:
python3 -c "import json,sys; ..." jq가 있으면jq -r 'select(.level=="warn") | .ts' /opt/data/app.jsonl | sort | head -1- 흔한 실수 1: 4번에서 반올림하는 것. 내림입니다.
- 흔한 실수 2: 6번에서 error 의 첫 시각을 적는 것. warn 이 더 앞에 있고, 그 간격이 이 실습의 요점입니다.
단계 8개
- 작업 디렉터리 만들기
- 에러 로그 수 세기
- 원인 테이블 알아내기
- 평균 지연 구하기
- 느린 요청 수 세기
- 최초 경고 시각 찾기
- 직전 배포 버전 찾기
- 인과 정리하기