지금 판단해야 하는 사람을 위한 문서. 짧고, 영향 범위와 다음 보고 시각이 핵심입니다.
이 파트에서 다루는 내용
이 보고서의 목적은 재발 방지입니다
Part 4의 진행 중 보고와는 목적이 다릅니다. 그건 받는 사람의 판단을 위한 문서였고, 이건 다음번을 위한 문서입니다.
그래서 독자도 다릅니다. 지금 상사가 아니라 6개월 뒤 비슷한 증상을 만난 사람입니다. 그 사람이 검색해서 찾아 읽고 시간을 아낄 수 있으면 이 보고서는 성공한 것입니다.
문서를 쓰는 원칙 자체는 협업·성장 코스의 기술 문서 파트에서 다룹니다. 여기서는 장애 보고서에 고유한 부분만 봅니다.
나중에 같은 일을 겪을 사람을 위한 문서. 타임라인과 근본 원인, 재발 방지 조치가 핵심입니다.
복구 직후 며칠 안에 씁니다. 미루면 세부가 흐려지고, 흐려진 뒤에 쓰면 추측이 사실처럼 섞입니다.
구성은 다섯 덩어리입니다
- 영향은 가능한 한 수치로 씁니다. "많은 사용자"보다 "약 1,200명"이 훨씬 유용합니다. 우선순위를 정할 때 근거가 됩니다.
- 타임라인의 시각은 Part 5에서 정렬한 로그를 그대로 씁니다. 그래서 정렬 결과를 파일로 남겨 두라고 한 것입니다.
- 재발 방지 항목에 담당자와 기한이 없으면 그 항목은 실행되지 않습니다. 예외 없습니다.
- 완료된 것과 예정인 것을 구분해 표시합니다. 완료 항목이 있으면 보고서의 설득력이 완전히 달라집니다.
[장애 원인 규명 보고서] 주문 조회 지연
■ 요약 (3줄)
외부 결제 시스템 응답 지연으로 요청 처리 스레드가 고갈되어
주문 조회가 1시간 45분간 지연됨. 외부 호출에 타임아웃이
설정되지 않은 것이 근본 원인.
■ 타임라인
14:20 외부 결제 시스템 응답 지연 시작 (상대 시스템 배포)
14:23 주문 조회 응답시간 증가 시작 (사후 로그 확인)
14:41 사용자 신고 접수
14:48 영향 범위 파악 및 1차 보고
15:10 스레드 덤프 확보, 결제 연동 대기 확인
15:35 결제 연동 일시 차단으로 부분 복구
16:05 외부 시스템 정상화, 전체 복구
■ 영향
- 주문 조회 기능 지연 (평균 30초 이상), 약 1시간 45분
- 영향 사용자 약 1,200명 / 실패 요청 약 8,400건
- 주문 등록·수정은 정상
■ 원인
직접 원인 : 요청 처리 스레드 200개가 모두 결제 연동 응답 대기
근본 원인 : 결제 연동 HTTP 클라이언트에 읽기 타임아웃 미설정
외부 장애가 우리 시스템 전체 장애로 번지는 구조
■ 재발 방지
[완료] 결제 연동 읽기 타임아웃 5초 설정 (7/30 배포)
[완료] 결제 연동 응답시간 지표 노출 및 임계치 알림 (7/30)
[예정] 외부 연동 전반의 타임아웃 설정 점검 - 담당 OOO, 8/9까지
[예정] 외부 연동 실패 시 기능 축소 동작 설계 - 담당 OOO, 8/23까지타임라인에 "사후 로그 확인"처럼 나중에 알게 된 사실을 표시해 두면, 당시 우리가 무엇을 몰랐는지가 드러납니다. 이게 대응 절차를 개선할 단서가 됩니다.
직접 원인에서 멈추면 재발합니다
"스레드가 고갈됐다"는 직접 원인입니다. 여기서 멈추면 대응은 스레드를 늘리는 것이 되고, 같은 장애가 다시 납니다.
왜 고갈됐는지, 그리고 왜 그런 구조가 가능했는지까지 가야 합니다. 위 예시에서는 외부 호출에 타임아웃이 없었다는 것, 그리고 외부 장애가 전체 장애로 번지는 구조라는 것이 근본 원인입니다.
스레드 고갈 → 왜 → 외부 응답 대기 → 왜 → 타임아웃 없음 → 왜 → 연동 추가 시 점검 항목에 없었음. 여기서 구조가 보입니다.
"우리가 바꿀 수 있는 것"에 도달하면 멈춥니다. 더 파고들면 억지스러워지고 실행 가능한 조치가 안 나옵니다.
다섯 번을 꼭 채울 필요는 없습니다. 횟수를 맞추려다 없는 인과를 만들어 내면 오히려 해롭습니다.
장애는 대개 여러 조건이 겹쳐 납니다. 하나로 억지로 좁히지 말고 겹친 조건들을 그대로 씁니다.
사람을 원인으로 쓰면 아무것도 안 바뀝니다
"담당자가 설정을 누락했다"로 끝나는 보고서가 있습니다. 사실일 수는 있지만 재발 방지에는 아무 쓸모가 없습니다. 사람은 또 실수하기 때문입니다.
물어야 할 것은 그다음입니다. 왜 그 실수가 가능했는가. 왜 배포 전에 걸러지지 않았는가. 왜 아무도 이상하다고 느끼지 못했는가. 여기서 나오는 답이 실제로 바꿀 수 있는 것들입니다.
현실적인 이유도 있습니다. 보고서가 사람을 지목하는 문화가 되면, 다음부터 아무도 사실대로 말하지 않습니다. 정보가 사라지면 원인 규명 자체가 불가능해집니다.
[사람을 지목]
원인: 담당자가 타임아웃 설정을 누락함
조치: 담당자 교육, 주의 당부
[구조를 다룸]
원인: 외부 연동 추가 시 타임아웃 설정이 점검 항목에 없어
누락 여부를 아무도 확인하지 못하는 상태였음
조치: 외부 연동 체크리스트에 타임아웃 항목 추가
기본 타임아웃을 가진 공통 클라이언트 제공
설정 누락 시 기동 단계에서 경고아래쪽은 담당자가 누구였든 같은 조치가 나옵니다. 그게 구조를 다룬다는 뜻입니다. 위쪽 조치는 실행 여부를 확인할 방법조차 없습니다.
정직하게 쓰는 것이 결국 유리합니다
우리 책임인 부분을 축소하거나 외부 탓으로 돌리고 싶은 유혹이 있습니다. 특히 고객사에 제출하는 보고서라면 더 그렇습니다.
다만 위 예시에서 보듯 외부 시스템이 느려진 것은 계기이고, 그것이 우리 전체 장애로 번진 것은 우리 구조 문제입니다. 이걸 외부 탓으로만 쓰면 같은 일이 다른 연동에서 또 납니다.
그리고 모르는 것은 모른다고 씁니다. Part 4의 원인 미규명 종료 보고와 같은 원칙입니다. 그럴듯한 원인을 지어 넣으면 다음 사람이 그걸 믿고 엉뚱한 곳을 팝니다.
외부 시스템이 계기였다면 그 사실은 씁니다. 다만 "외부 시스템 장애"에서 끝내지 않고, 그것이 우리에게 번진 경로를 함께 씁니다. 외부는 우리가 못 고치지만 번지는 경로는 고칠 수 있습니다. 재발 방지 조치는 거기서 나옵니다.
다시 읽히지 않으면 쓴 의미가 없습니다
- **증상 키워드로 검색되게 씁니다.** 6개월 뒤 그 사람은 원인을 모르는 상태로 검색합니다. "주문 조회 지연", "스레드 고갈", "응답 없음" 같은 말이 제목과 본문에 있어야 찾힙니다.
- **한곳에 모읍니다.** 메일이나 메신저에만 남으면 사실상 없는 것입니다. 팀이 찾아볼 수 있는 위치에 둡니다.
- **재발 방지 항목을 실제 일정에 넣습니다.** 보고서에만 적혀 있으면 대부분 실행되지 않습니다. 담당과 기한을 붙여 일감으로 등록해야 합니다.
- **나중에 결과를 덧붙입니다.** 예정이던 항목이 완료되면 보고서에 표시합니다. 이게 없으면 다음 사람이 그 조치가 됐는지 안 됐는지 모릅니다.
- 협업·성장 코스에서 다룬 결정 기록과 같은 성격입니다. 당시의 판단 근거를 남겨 두면 나중에 왜 이렇게 됐는지를 설명할 수 있습니다.