
Datadog 알람에서 결함 Issue를 자동 생성하여 AI가 수정하게 하기 — 서버리스 배선 레시피
요약
Datadog 알람 발생 시 GitHub Issue를 자동으로 생성하고, Claude Code를 활용해 AI가 결함을 조사하여 수정 PR까지 생성하는 서버리스 워크플로우를 소개합니다. Webhook과 repository_dispatch 방식을 사용하여 서버리스 환경에서 안정적인 자동화 파이프라인을 구축하는 방법을 다룹니다.
핵심 포인트
- Datadog Webhook과 GitHub repository_dispatch를 활용한 서버리스 자동화
- HTML 코멘트를 이용한 중복 Issue 생성 방지 로직 구현
- bug-fix 라벨을 트리거로 Claude Code의 자동 수정 루프 연결
- 인간의 개입을 최소화하고 최종 Merge 판단만 수행하는 워크플로우
비유: 「화재 경보기가 소방서와 직결되어 있지 않은」 문제
Datadog 알람을 Slack으로 보내고 있는 현장은 많을 것이라고 생각합니다. 하지만 그것은 화재 경보기가 「울리기만 하는」 상태입니다.
- 울림 → 누군가 인지함 → 누군가 Issue를 생성함 → 누군가 조사함
- 야간이나 휴일에는 「누군가」가 없으므로, 월요일 아침에 Slack을 거슬러 올라가며 찾아내야 함
- 동일한 알람이 3번 울리면, Issue가 3개 생성됨 (또는 하나도 생성되지 않음)
이 「누군가」 부분을 전부 배선(Wiring)으로 연결하면 다음과 같이 됩니다.
알람 발생부터 수정 PR 생성까지 인간이 등장하지 않습니다. 인간의 업무는 마지막 머지(Merge) 판단뿐입니다.
이 기사에서는 전반부의 배선(Datadog → Issue 자동 생성)을 만듭니다. 후반부(Issue → AI가 조사하여 수정 PR)는 #5 기사에서 해설한 Issue 주도 플로우(Issue-driven flow)의 결함 버전으로, bug-fix 라벨이 붙은 Issue를 Claude Code의 루프가 포착하는 구성입니다.
설계의 결론부터
먼저 요점을 정리합니다. 3가지 선택지를 검토하여, Webhook → repository_dispatch 방식으로 결정했습니다.
| 방식 | 평가 | 이유 |
|---|---|---|
| Claude Code로 Datadog API를 상주 폴링(Polling) | ❌ | 세션 의존적 (PC를 닫으면 종료됨). 플래핑(Flapping)으로 인해 스팸화되기 쉬움. 상시 토큰 소비 |
| Slack의 알람 메시지를 파싱(Parse) | ❌ | 메시지 문구 파싱은 취약함. 모니터 ID를 확실하게 가져오기 어려움 |
Datadog Webhook → GitHub repository_dispatch | ✅ | 서버리스 · 세션 비의존적. 모니터 ID가 payload로 직접 전달됨. 대상 모니터 필터링을 Datadog 측에서 제어 가능 |
서버도 Lambda도 필요 없습니다. 수신 창구는 GitHub 표준 API(repository_dispatch)이며, GitHub Actions가 그대로 생성 처리를 실행합니다.
단계 1: 생성할 GitHub Actions 작성하기
Issue를 집약하고 있는 리포지토리(저희는 다중 리포지토리의 Issue를 하나로 모으는 ideation-hub 패턴을 사용하고 있습니다)에, repository_dispatch를 받는 workflow를 배치합니다.
name: Datadog 알람 → 결함 Issue 생성
on:
repository_dispatch:
...
포인트는 2가지입니다.
① 숨김 마커로 중복 방지. Issue 본문에 <!-- datadog-monitor:<모니터ID> -->라는 HTML 코멘트를 삽입하여, 동일한 모니터가 재발하면 신규 Issue가 아닌 기존 Issue에 코멘트를 추가하도록 합니다. 플래핑(발생 ⇄ 회복의 반복)하는 모니터가 있더라도 Issue 목록이 지저분해지지 않습니다.
② bug-fix 라벨이 하류(Downstream)로의 연결점. 이 라벨을 Claude Code의 상주 루프(/loop + custom skill)가 포착하여, 「조사 → 실패하는 재현 테스트 작성 → 수정 → 셀프 리뷰 → PR」까지 자동으로 진행합니다. 라벨을 상태 머신(State machine)으로 사용하는 설계는 #5와 동일합니다.
단계 2: fine-grained PAT를 발행하기
Datadog에서 repository_dispatch를 호출하기 위한 인증 토큰을 만듭니다.
- GitHub 우측 상단 아이콘 → Settings → 왼쪽 사이드바 최하단 Developer settings → Personal access tokens → Fine-grained tokens - Resource owner에서 대상 조직을 선택
- Repository access: Only select repositories → Issue 집약 리포지토리만 선택 - Permissions → Repository permissions → Contents: Read and write (
repository_dispatch포함)
를 트리거하는 데 필요합니다.
권한을 「1개 리포지토리 × Contents 전용」으로 제한할 수 있는 것이 fine-grained PAT의 장점입니다. classic PAT의 repo 스코프를 사용하면 모든 리포지토리에 쓸 수 있는 토큰을 Datadog에 맡기게 되므로 피해야 합니다.
단계 3: Datadog에 Webhook 만들기
Datadog의 Integrations → Webhooks에서 생성합니다. API로도 생성할 수 있습니다:
curl -X POST "https://api.datadoghq.com/api/v1/integration/webhooks/configuration/webhooks" \
-H "DD-API-KEY: $DD_API_KEY" -H "DD-APPLICATION-KEY: $DD_APP_KEY" \
-H "Content-Type: application/json" \
...
주의할 점이 하나 있습니다. 본문의 변수는 $EVENT_MSG가 아니라 **$TEXT_ONLY_MSG**를 사용하세요.
$EVENT_MSG는 마크다운 (markdown) 문법이나 인용부호를 포함하기 때문에, 페이로드 (payload)의 JSON을 파괴하여 GitHub 측에서 4xx 에러가 발생할 수 있습니다 (Datadog의 변수 확장 시 JSON 이스케이프 (JSON escape)를 해주지 않기 때문입니다). 어차피 상세 정보는 이슈 생성 후 AI나 사람이 Datadog을 직접 확인하므로, Webhook으로 전달하는 본문은 일반 텍스트 (plain text)로도 충분합니다. 참고로 PAT의 로테이션 (rotation)은 이 Webhook 정의의 custom_headers를 교체하기만 하면 됩니다:
# 이름 지정으로 PUT (목록 조회 엔드포인트는 존재하지 않음. 이름 지정 GET/PUT만 가능)
curl -X PUT "https://api.datadoghq.com/api/v1/integration/webhooks/configuration/webhooks/github-bugfix-issue" \
-H "DD-API-KEY: $DD_API_KEY" -H "DD-APPLICATION-KEY: $DD_APP_KEY" \
...
단계 4: 모니터에 알림 대상 추가하기 — 이 부분이 가장 중요합니다
Webhook을 만든 것만으로는 아무 일도 일어나지 않습니다. 어떤 모니터가 이슈를 생성할지는, 모니터의 message에 @webhook-<이름>을 작성하느냐에 따라 결정됩니다. 이것이 실질적인 「자동 생성 대상 범위의 설계」입니다.
저희는 모든 모니터에 적용하지 않고, 크리티컬한 항목(운영 장애, 금전적 손실이나 데이터 불일치와 직결되는 것)만으로 범위를 좁혔습니다:
- API 5xx 에러 급증 (운영 환경)
- DLQ 메시지 수신 (시스템 장애 시그널)
- 비동기 태스크의 failed 종료 (결제·알림 처리 누락)
- 외부 결제 인프라와의 사용자 연동 실패
나아가, message 작성 방식을工夫하여 「운영 환경의 알람이 발생할 때만」 전송되도록 합니다:
{{#is_alert}}{{#is_match "env.name" "prod"}}@webhook-github-bugfix-issue{{/is_match}}{{/is_alert}}
{{#is_alert}}— 복구 알림(Recovery) 시에는 보내지 않음. 이것이 없으면 Recovered 상태가 될 때마다 이슈에 댓글이 달려 번거로워집니다.{{#is_match "env.name" "prod"}}— dev/stg 환경의 발생 시에는 보내지 않음 (env로 그룹화된 모니터의 경우.is_match는 부분 일치이므로 `
curl -X POST "https://api.github.com/repos/your-org/ideation-hub/dispatches" \
-H "Authorization: Bearer <PAT>" -H "Accept: application/vnd.github+json" \
-d '{"event_type":"datadog-alert","client_payload":{"monitor_id":"wiring-test","title":"[TEST] 配線テスト","message":"確認後クローズ","priority":"P5","link":"https://app.datadoghq.com/monitors"}}'
204가 반환되고, Actions가 실행되어 Issue가 생성된다면 GitHub 측 설정은 완료된 것입니다 (테스트용 Issue는 닫아둡니다). 동일한 명령어를 다시 실행하면, 이번에는 신규 생성이 아니라 댓글이 추가되는 것을 확인할 수 있습니다. Datadog 측에서는 다음 실제 알람이 첫 번째 실전 테스트가 됩니다.
보완: 대상 외 알람은 "URL만 전달하는" 수동 생성
크리티컬(Critical) 범주 이외의 알람까지 자동으로 생성하면 Issue 목록이 노이즈로 가득 차기 때문에, 그 부분은 사람이 판단하여 생성하는 구성으로 만들었습니다. 다만 생성 작업 자체는 Claude Code의 custom skill에 맡깁니다:
/datadog-to-issue https://app.datadoghq.com/monitors/12345678
Slack에 올라온 Datadog 링크를 붙여넣기만 하면, skill이 다음 과정을 진행합니다:
- URL로부터 모니터 ID를 해결 (이벤트 URL인 경우 Events API를 통해
monitor_id로 해결) - 모니터 상세 정보와 최근 7일간의 발생 횟수를 취득
- 발생 시간대의 에러 로그 및 APM의 error span을 가볍게 조회하여 "조사 단서"를 첨부
- 동일한 숨김 마커로 중복 체크 (자동 생성분과 상호 중복 감지 가능)
- 중요도(🔴 크리티컬 / 🟠 운영 장애 / 🟡 경미)를 판정하여 생성
까지 진행합니다. 자동 경로와 수동 경로에서 마커의 형식을 통일해 두는 것이 은근히 중요한데, 이를 맞추지 않으면 "자동으로 생성된 모니터를 수동으로 한 번 더 생성"하는 일이 발생합니다.
skill을 만드는 방법 자체는 #2 custom skill 설계 패턴을 참조해 주세요.
주의사항(ハマりどころ) 요약
실제로 배선하며 겪었거나 회피했던 사항들입니다.
| 함정 | 대책 |
|---|---|
$EVENT_MSG가 JSON을 파괴함 | $TEXT_ONLY_MSG를 사용한다. 자세한 내용은 생성 후 Datadog을 직접 확인한다 |
| 복구 알람(Recovery) 시에도 Webhook이 발송됨 | {{#is_alert}}로 감싼다 |
| dev/stg 발생 시에도 생성됨 | {{#is_match "env.name" "prod"}}로 감싼다 (그룹화 방식에 따라 queuename 등으로 변경) |
| 플래핑(Flapping)으로 인해 Issue가 대량 생성됨 | 마커를 통한 중복 방지 + 애초에 대상 모니터를 좁힌다 |
| Error Tracking 계열 모니터는 모두 동일한 모니터 ID를 가짐 | 모니터 ID만으로 중복 판정을 하면 무관한 버그가 하나의 Issue로 합쳐진다. 이벤트 내의 issue id를 중복 키로 병용한다 |
| PAT 만료로 인해 경로가 무통보 중단됨 | 만료일을 관리한다. 로테이션은 Webhook 정의의 custom_headers 교체만으로 가능하다 |
| Webhook 목록 API가 없음 | GET /api/v1/integration/webhooks/configuration/webhooks/<name>의 이름 지정 방식만 지원한다. 이름은 직접 기록해 둔다 |
요약
- Datadog Webhook →
repository_dispatch를 통해 서버리스로 "알람 → Issue" 배선 가능 - → GitHub Actions로 연결
- 대상은 크리티컬 범위로만 한정하고,
{{#is_alert}}× env 조건으로 "운영 환경 발생 시에만" 작동하도록 설정 - 숨김 마커를 사용하여 재발 시에는 댓글 추가로 처리함으로써 Issue 목록을 보호
- 생성된 Issue는
bug-fix...
레이블을 통해 AI의 자동 수정 루프 (AI automatic fix loop)에 연결되어, 인간은 마지막 머지 (merge) 판단만 수행하게 됩니다. 운영상의 핵심 주의 사항은 다음과 같습니다.
PAT (Personal Access Token)의 유효 기간.
이 부분은 시스템적으로 방어할 수 없으므로 반드시 기록을 남겨야 합니다.
"알람을 확인하고, Issue를 생성하고, 조사를 시작하는" 초동 조치의 30분은, 완전히 배선 (wiring)만으로 없앨 수 있는 시대가 되었습니다. 소방서 직결 방식이며, 적극 추천합니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기