지능형 장애 알림 PRD
Background
요구사항은 “P95 이상의 API 레이턴시가 급증할 경우 Discord webhook으로 알림을 발생시키되, 어떤 에러인지·원인·해결방법을 함께 조사해 알림에 포함”할 것을 명시한다. 현재 코드베이스에는 Discord 연동이 전혀 없다. domain/mcp에 McpAnomalyDetector·McpAnomalyEventWorker AI 파이프라인이 이미 존재하지만, 이는 MCP(AI 에이전트) 토큰 오남용 이상탐지 용도이며 인프라 레이턴시 알림과는 목적이 다르다 — 사용자 답변에 따라 이 기존 파이프라인은 재사용하지 않고 완전히 별도로 신규 구축한다.
반면 domain/notification에는 이미 NotificationChannel(채널 종류 VO)·NotificationChannelGateway(채널별 발송 인터페이스)·NotificationDomainService로 구성된 채널 확장 가능한 알림 발송 구조가 존재한다. 본 과제의 Discord 알림은 이 구조를 재사용한다 — NotificationChannel에 DISCORD 값을 추가하고 NotificationChannelGateway 구현체(DiscordNotificationGatewayImpl)로 편입하며, 별도의 독립 알림 파이프라인을 신설하지 않는다. “원인 조사”(텔레메트리 원지표 첨부)는 이 발송 구조 앞단에서 텔레메트리(Prometheus/Loki/Tempo)를 조회해 알림 컨텐츠를 구성하는 별도 단계로 추가된다.
이 과제는 [옵저버빌리티 스택 도입](../옵저버빌리티 스택 도입/PRD.md)에서 구축하는 Prometheus·Loki·Tempo 3종 데이터 소스와 env 태그를 전제로 하며, 그 스택이 없으면 원인 분석에 쓸 데이터도, 환경 구분도 불가능하다.
Problem Definition
- 레이턴시 급증을 감지해도 알림을 받을 방법이 없다 — Discord 채널이
NotificationChannel에 없다. - 임계치 위반 사실만 아는 것으로는 원인 파악에 별도의 수동 조사(Grafana 탐색, 로그 grep)가 필요해 초동 대응이 늦어진다.
- 알림 소스가 레이턴시 급증(본 과제) 외에도 [마케팅 이벤트 고부하 대응](../마케팅 이벤트 고부하 대응/PRD.md)의 오버셀 알림, [배포 파이프라인·환경 분리](../배포 파이프라인·환경 분리/PRD.md)의 배포 실패 알림처럼 여러 소스에서 발생하는데, 이를 하나의 파이프라인에서 구분 없이 처리하면 심각도 판단이 뒤섞인다.
- dev·prod 두 환경이 분리되면([배포 파이프라인·환경 분리](../배포 파이프라인·환경 분리/PRD.md)) 두 환경의 알림을 구분할 기준이 필요하다 — 단 이는 “환경별 심각도 2단계”가 아니라, 아래 정의하는 심각도 등급·소스 차원과 별개 태그로 다뤄야 한다.
- 쿨다운(중복 억제) 기준이 “알람”(임계치 위반 신호)인지 “원인”(텔레메트리 조회로 확인되는 근본 원인)인지 정의된 적이 없다 — 원인은 텔레메트리 조회가 끝나야만 알 수 있으므로, 원인 기준으로 억제를 판단하면 억제 여부를 결정하기 위해 매번 텔레메트리를 먼저 조회해야 해 비용·레이턴시가 커진다.
Goals / Non-Goals
Goals
- API별 P95 레이턴시 임계치 위반을 감지해 Discord로 알림을 발송한다.
- 알림 소스·심각도 모델을 정의한다: 심각도는
info/warn/critical3등급이며, 알림 소스 차원(latency/oversell/deployment등)과 독립적으로 태깅된다. 예: 레이턴시 급증은source=latency, severity=warn(지속 시간에 따라critical로 승격), 오버셀은source=oversell, severity=critical(항상), 배포 실패는source=deployment, severity=critical. [마케팅 이벤트 고부하 대응](../마케팅 이벤트 고부하 대응/PRD.md)의 오버셀 알림과 [배포 파이프라인·환경 분리](../배포 파이프라인·환경 분리/PRD.md)의 배포 실패 알림은 이 모델을 따라 소스 태그를 붙여 동일 파이프라인으로 흘러온다. - 알림 발송 전 Prometheus(메트릭)·Loki(로그)·Tempo(trace) 데이터를 조회해 텔레메트리 원지표 스냅샷을 알림 본문에 자동 첨부한다.
- 알림 신호(알람) 단위로 쿨다운을 적용해 반복 발생을 억제한다 — 원인(텔레메트리 조회 결과)이 아니라 신호 자체를 기준으로 판단한다(아래 FR 참조).
- 기존
NotificationChannel·NotificationChannelGateway구조에 Discord 채널을 편입한다. - 발생 환경은 기존
env태그(local/dev/prod)로 알림에 명시한다.
Non-Goals
- 자동 원인 조치(auto-remediation) — 예를 들어 임계치 위반 시 자동 재시작·자동 스케일아웃은 다루지 않는다. 사람이 알림을 보고 판단·조치한다.
- LLM 기반 원인 추론·해결책 자동 생성 — 현재는 텔레메트리 원지표를 조회해 알림 본문에 그대로 첨부하는 데까지만 다룬다. LLM으로 원인·해결방법을 추정하는 것은 다루지 않는다.
- 실제 클라우드 프로덕션 환경 대응 — 본 과제는 로컬 docker-compose 기준 dev·prod 두 환경에 한정한다.
User Scenarios
페르소나: 운영자(본인).
- 해피 패스: prod 환경에서 특정 API의 P95 레이턴시가 500ms를 5분간 초과하면(
source=latency), Discord에 “환경: prod / 심각도: warn / 원인(원지표): HikariCP active 50/50, Loki 커넥션 타임아웃 로그 120건, 느린 trace 3건” 형태로 텔레메트리 원지표 스냅샷을 담은 메시지를 수신한다. - 예외 — 텔레메트리 원지표 조회 실패: 텔레메트리 조회가 비거나 실패하면, 원지표 없이 “임계치 위반 발생” 신호(에러) 정보만 담은 기본 알림을 즉시 전송한다 — 원인 조사 실패가 알림 자체를 막지 않는다.
- 억제 — 반복 알림: 동일 API·동일 소스(
latency)의 알람 신호가 15분 내 재차 발생해도, 텔레메트리 조회 결과와 무관하게 신호 자체가 이미 쿨다운 중이므로 중복 알림은 억제된다. - 소스 구분 — 오버셀: [마케팅 이벤트 고부하 대응](../마케팅 이벤트 고부하 대응/PRD.md)에서 오버셀이 감지되면
source=oversell, severity=critical로 태깅되어, 동시에 발생 중인latency알림과 별개의 쿨다운·별개의 메시지로 즉시 발송된다. - 환경 구분: dev 환경에서 발생한 알림과 prod 환경에서 발생한 알림은 메시지에
env태그로 명시되어 즉시 구분된다.
Benchmarking
| 제품명 | 카테고리 | 참조 패턴 | URL |
|---|---|---|---|
| Datadog Bits AI SRE(Bits Investigation) | AIOps 자동 장애 진단 에이전트 | 텔레메트리(메트릭·로그·trace)를 상시 읽어 알림 발생 시 원인 데이터를 자동 조사하고 대응 채널(Slack·PagerDuty 등)로 알림을 보내는 구조 — “임계치 위반 감지 → 텔레메트리 조회 → 원지표 첨부 알림”이라는 본 과제의 핵심 흐름을 참조(단, 본 과제는 LLM 상관분석 없이 원지표를 그대로 첨부) | Bits Investigation — Datadog |
| PagerDuty AIOps | 인시던트 관리·알림 플랫폼 | 이상 신호를 상관분석해 노이즈를 줄이고 온콜 담당자의 초동 대응 시간을 단축하는 패턴 — 본 과제의 쿨다운·알림 억제 요구사항의 참조 사례(요약 생성은 미채택) | How PagerDuty Enhances AI Monitoring and LLMOps |
Functional Requirements
| ID | 요구사항 | 우선순위 |
|---|---|---|
| FR-1 | API별 P95 레이턴시 임계치 규칙을 정의한다(규칙 엔진 선택은 Open Questions에서 결정) | P0 |
| FR-2 | 임계치 위반 시 알림 파이프라인을 트리거한다 | P0 |
| FR-3 | 알림 소스·심각도 모델(source∈{latency,oversell,deployment,…} × severity∈{info,warn,critical})을 정의하고, 모든 알림에 두 태그를 부여한다 | P0 |
| FR-4 | 알림 트리거 시 최근 10분 구간의 Prometheus 메트릭 요약, Loki 에러 로그 샘플, Tempo 느린 trace 샘플을 조회해 알림 본문에 첨부할 원지표 스냅샷을 구성한다 | P0 |
| FR-5 | 조회한 텔레메트리 원지표 스냅샷(메트릭 요약, 에러 로그 샘플, 느린 trace 샘플)을 알림 본문에 포함해, 기존 NotificationChannel에 추가한 DISCORD 채널로 NotificationChannelGateway 구현체(DiscordNotificationGatewayImpl)를 통해 발송한다 | P0 |
| FR-6 | 알림 메시지에 발생 환경(기존 env 태그: local/dev/prod)을 명시한다 | P0 |
| FR-7 | 쿨다운은 알람 신호(API 엔드포인트 + source + severity 조합) 단위로 판단한다 — 조회한 원지표(원인)가 같은지 다른지는 쿨다운 판단에 사용하지 않는다. 동일 신호는 15분간 재알림을 억제한다 | P1 |
| FR-8 | 텔레메트리 조회가 비거나 실패해도 신호(에러) 정보만 담아 발송한다(쿨다운 판단은 FR-7 기준으로 이미 완료된 상태이므로 원지표 첨부 여부와 무관하다) | P1 |
| FR-9 | 발송된 알림 이력을 저장해 사후 분석에 활용한다 | P2 |
Non-Functional Requirements
- 임계치 위반 감지부터 Discord 알림 도달까지 P95 60초 이내(텔레메트리 조회 포함).
- 텔레메트리 원지표 첨부율 90% 이상(조회 실패분은 FR-8에 따라 신호 정보만 담아 발송).
- 동일 신호(엔드포인트+source+severity)의 알림은 15분당 1건 이하로 제한된다.
Operations
- 알림 파이프라인 자체의 실패율(텔레메트리 조회 실패율, Discord 전송 실패율)을 [옵저버빌리티 스택 도입](../옵저버빌리티 스택 도입/PRD.md) 대시보드에 노출한다.
- 알림 파이프라인이 정상 동작 중임을 확인하기 위해 1시간 주기 self-check 메시지를 발송한다 — self-check가 끊기면 알림 시스템 자체의 장애로 간주한다.
Success Metrics
- 임계치 위반 상황 재현 테스트에서 알림 도달 성공률 100%.
- 텔레메트리 원지표를 첨부한 알림 비율(조회 실패로 신호 정보만 담은 건 제외) 90% 이상.
- 모든 알림의
source·severity·env태그 누락 0건.
Milestones
- M1: 임계치 규칙 + 알림 소스·심각도 모델 + 기본 알림(원인 조사 없이, FR-1~FR-3).
- M2: 텔레메트리 원지표 조회·첨부 + 기존 notification 채널 편입(FR-4~FR-6).
- M3: 쿨다운·조회 실패 시 신호 정보만 발송(FR-7, FR-8).
의존: [옵저버빌리티 스택 도입](../옵저버빌리티 스택 도입/PRD.md)이 선행돼야 FR-4의 데이터 소스(Prometheus/Loki/Tempo)와 env 태그가 존재한다. [배포 파이프라인·환경 분리](../배포 파이프라인·환경 분리/PRD.md)가 선행돼야 FR-6의 환경 구분이 실질적 의미를 갖는다. [마케팅 이벤트 고부하 대응](../마케팅 이벤트 고부하 대응/PRD.md)의 오버셀 알림, [배포 파이프라인·환경 분리](../배포 파이프라인·환경 분리/PRD.md)의 배포 실패 알림은 FR-3의 소스 태그(oversell, deployment)로 이 파이프라인을 통해 발송된다.
Open Questions
- 임계치 규칙 엔진을 Prometheus Alertmanager로 할지 Grafana Alerting으로 할지 결정해야 한다(FR-1).
- 알림 대상 API 범위를 전체 API로 할지, 핵심 트랜잭션 API(결제·예약·티케팅 등)로 한정할지 결정해야 한다.
Document History
| 날짜 | 변경 내용 |
|---|---|
| 2026-07-03 | 최초 작성 (dev/prod 환경별 알림 심각도 구분 반영) |
| 2026-07-03 | 재검수 1차 반영: 심각도 모델을 dev/prod 2단계에서 info/warn/critical 등급 + source(latency/oversell/deployment) 차원으로 확장(FR-3), 쿨다운 dedup 기준을 “원인”이 아닌 “알람 신호”로 명확화(FR-7), FR-4 “최근 N분”을 10분으로 수치화, FR-1의 Alertmanager/Grafana Alerting 택일을 Open Questions로 이관, 기존 notification 도메인(NotificationChannel/NotificationChannelGateway)에 Discord를 편입하는 방향으로 AS-IS·FR-5 수정, 새 environment 라벨 대신 기존 env 태그 재사용으로 통일 |
| 2026-07-06 | LLM 원인분석·해결방법 제거 — process 단계를 텔레메트리 원지표 조회·첨부로 축소(FR-4/FR-5/FR-8 수정), 상태 ANALYZED/FALLBACK→ENRICHED 단일화 |