[인턴] 에러 알림 체계 리팩토링
에러 알림을 “소음”에서 “신호”로 바꾸는 방법
운영 환경에서는 알림이 많아질수록 진짜 중요한 문제가 묻히기 쉽습니다.
이번 글은 민감한 내부 규칙을 직접 드러내기보다, 관제실의 신호 체계라는 비유로 에러 운영 방식을 정리해봅니다.
왜 분류 체계가 필요한가
에러를 수집하는 것만으로는 운영이 좋아지지 않습니다.
관제실 관점에서 필요한 질문은 보통 아래와 같습니다.
- 이 알림은 지금 당장 반응해야 하는가?
- 바로 울려야 하는 벨인가, 묶어서 봐도 되는 기록인가?
- 반복되는 경고를 장애처럼 다루고 있지는 않은가?
핵심은 “많이 모으는 것”보다 “같은 기준으로 구분하는 것” 입니다.
비유로 보는 신호 단계
저는 내부적으로 에러를 “신호등 색”처럼 다루는 방식으로 정리했습니다.
Red: 핵심 흐름이 멈춘 상태. 즉시 반응이 필요한 신호Orange: 핵심 품질이 크게 흔들리는 상태. 빠른 확인이 필요한 신호Yellow: 일부 기능 저하나 일시적 실패. 업무 시간 내 확인 가능한 신호Blue: 모니터링성 이벤트. 추세 관찰과 개선 후보
중요한 점은 이름이 아니라, 팀이 동일한 해석을 공유하는가 입니다.
구현할 때 잡은 원칙
1) 수집 입구를 하나로 만든다
에러를 보내는 경로를 공통 함수로 통일하면,
- 신호 단계 누락 방지
- 심각도 매핑 일관성 확보
- 부가 정보 형식 통일
같은 효과를 한 번에 얻을 수 있습니다.
type Signal = "RED" | "ORANGE" | "YELLOW" | "BLUE";
function reportOperationalError(
error: Error,
context: {
signal: Signal;
labels?: Record<string, string>;
meta?: Record<string, unknown>;
},
) {
// 실제 키 이름이나 룰은 서비스별로 다르고, 여기서는 구조만 예시로 남긴다.
return sendToMonitoringSystem({ error, ...context });
}
2) 객체보다 Error를 기본으로 둔다
디버깅에서 가장 큰 차이는 스택트레이스 유무였습니다.
문자열이나 일반 객체만 보내기보다, 가능한 Error 기반으로 맞추는 편이 분석 속도가 훨씬 안정적이었습니다.
3) “기록”과 “호출”을 분리한다
모든 이벤트를 즉시 알리면 피로도가 급격히 올라갑니다.
즉시 반응이 필요한 신호와, 묶어서 확인해도 되는 신호를 분리해야 운영이 오래 갑니다.
마이그레이션할 때 본 체크 포인트
전환 과정에서는 아래 패턴부터 정리하면 빠르게 효과를 볼 수 있었습니다.
- 분류 없이 바로 전송하는 예외 처리
- 호출 지점마다 제각각 붙어 있는 라벨/부가 정보
- 스택트레이스 없는 메시지 이벤트 남용
- 비슷한 스코프 설정 코드의 반복
정리 기준은 단순합니다.
- 모든 이벤트에 동일한 “신호” 필드를 붙인다.
- 신호와 심각도 매핑을 코드 한 곳에서 관리한다.
- 에러 본문과 맥락 데이터 구조를 팀 표준으로 맞춘다.
운영에서 얻은 변화
신호 체계를 도입하고 나서 가장 크게 달라진 점은 “반응 속도”보다 “반응 품질”이었습니다.
- 중요한 문제를 먼저 보는 합의가 생김
- 알림 피로도가 줄어듦
- 사후 분석 시 맥락 정보 품질이 높아짐
- “무엇이 진짜 장애인가”에 대한 팀 기준이 선명해짐
결국 운영의 목적은 에러를 많이 쌓는 것이 아니라,
의미 있는 신호를 빠르게 식별하고 정확하게 대응하는 것이라고 느꼈습니다.
Leave a comment