gyumin.log

SRE Observer - 장애 알럿을 AI로 자동 분석하기

🌿 자라는 중

목차

LINE Plus Home SRE 팀이 만든 장애 알럿 자동 분석 시스템을 읽고 정리한 노트. 출처: Building SRE Observer for alert root cause analysis

한 줄로 줄이면 **“새벽 3시에 사람이 30분 동안 하던 원인 추적을 AI에게 맡기되 AI가 근거 없이 확신하지 못하게 묶어둔 시스템”**이다. 기술보다 통제 설계가 인상적인 글이었다.

무엇을 풀려고 했나

알럿이 울리면 담당자는 대시보드에서 메트릭을 보고 로그를 검색하고 트레이스를 따라가고 필요하면 프로파일까지 확인한다. 흩어진 신호를 하나로 잇는 작업이 오직 사람 머릿속에서만 일어난다.

문제는 세 가지였다.

  • 알럿 노이즈: 근본 원인 하나가 수십 개 알럿으로 흩어진다. 업스트림 하나가 죽으면 그걸 호출하던 다운스트림들이 줄줄이 타임아웃 경보를 울린다. 담당자의 첫 일이 원인 분석이 아니라 “이 알럿들이 같은 장애인가?” 판별이 된다
  • 수동 RCA의 한계: 메트릭·로그·트레이스·프로파일을 각각 열어 직접 연결해야 한다. 신호 연결이 자동화되지 않은 채 사람 경험에만 의존한다
  • 기존 도구의 한계: Alertmanager는 라벨 기반 정적 그룹화라 서비스 의존 관계나 의미적 유사성을 못 본다. 상용 AIOps는 운영 환경에 맞게 동작을 통제할 제어권을 확보하기 어려웠다

전체 흐름 7단계

  1. Alert Ingestion - Mimir Ruler(PromQL 메트릭 규칙)와 Loki Ruler(LogQL 로그 규칙)가 이상 징후를 감지해 웹훅으로 알럿 발송
  2. Alert Correlation - 세 축으로 채점해 여러 알럿을 하나의 Incident로 수렴
  3. AI Analysis Agent - 가설-주도 RCA로 근본 원인과 영향 범위 도출
  4. 위험도 판단 - 근거 기반 가드레일을 통과한 신뢰도로 P1~P4 확정 또는 미확정
  5. 1차 대응 - 승인 없이 즉시 실행. Slack 멘션, 에스컬레이션, 티켓 생성
  6. 2차 대응 - Pod 재시작·롤백처럼 상태를 바꾸는 작업. 승인 게이트 통과 후 실행
  7. Post-Incident Knowledge - 확정된 P1 리포트를 사내 지식 베이스에 발행

각 단계는 독립적으로 돌지만 Incident Context Store라는 공용 저장소로 맥락을 공유한다. 인시던트 번호별로 알럿·분석 결과·증거가 쌓이는 구조다.

이 저장소가 왜 필요한지가 처음엔 안 와닿았는데 생각해보니 장애는 시간이 지나며 정보가 추가되기 때문이다. 처음엔 근거가 없어 “모르겠음”이었는데 10분 뒤 알럿 하나가 더 합류하며 결정적 단서가 들어올 수 있다. 그때 저장소를 다시 열어 재분석하면 추정이 확정으로 승격된다. 각 단계가 결과를 다음 단계로 직접 넘기기만 하는 구조였다면 이 되감기가 안 된다.

핵심 설계 1 - 알럿 묶기는 한 축만 믿지 않는다

새 알럿이 들어올 때마다 “기존 인시던트와 같은 건인가”를 세 축으로 채점해 가중 합산한다.

판단 기준가중치
SemanticLLM이 본 증상의 의미적 유사도높음
TopologyTempo 트레이스 기반 서비스 의존 관계중간
Temporal발생 시점의 근접성낮음

시간 축 가중치가 제일 낮은 게 포인트다. 비슷한 시각에 터졌다는 이유만으로 같은 장애라고 단정하지 않겠다는 뜻. 그리고 Semantic 축의 LLM 신뢰도가 기준에 못 미치면 그 축 점수를 0으로 떨어뜨리고 나머지 두 축으로 계속 판단한다. 한 축이 죽어도 시스템이 멈추지 않게 한 fallback 설계.

핵심 설계 2 - 근거 없는 결론은 강등시킨다

RCA는 가설-주도 방식이다. 다섯 가지 후보를 반드시 전부 열거하고 각각 판정한다.

deployment_change(배포 변경) / resource_exhaustion(자원 고갈) / external_dependency(외부 의존성) / code_bug(코드 결함) / infra_platform(인프라·플랫폼)

각 가설은 rule-in(직접 관측 신호로 충족), rule-out(반박 신호 확인), cannot-verify(검증 불가) 중 하나로 판정된다. 전부 rule-out이거나 검증 불가면 결론은 other, 즉 “모르겠다”다.

여기에 두 겹의 통제가 붙는다.

  • Evidence Ledger: 에이전트가 도구를 호출할 때마다 어떤 쿼리를 던졌고 뭘 관찰했는지 장부에 기록
  • Evidence Guardrail: 결론 단계에서 장부와 대조. 주장을 뒷받침하는 조회 기록이 없으면 categoryother로 강등하고 신뢰도를 깎는다. 예를 들어 자원 고갈이라 주장하면서 트렌드 쿼리나 OOM·재시작 확인이 없으면 신뢰도를 추가로 제한

심각도가 확정되려면 세 조건을 전부 만족해야 한다. 강등 사유가 없을 것, 인시던트가 확정 상태일 것, 보정된 신뢰도가 기준선 이상일 것. 한 번 확정되면 재분석 후에도 추정으로 되돌아가지 않는다(latch).

무한 탐색을 막는 장치도 있다. soft timeout(추가 수집 중단 신호), hard timeout(전체 실행 시간 상한), tool budget(도구 호출 횟수 상한).

핵심 설계 3 - 자동화의 경계선

“얼마나 자동화할까”가 아니라 **“어디까지 자동이고 어디서부터 사람인가”**로 프레이밍한 게 좋았다.

1차 대응은 승인 없이 즉시 실행하는데 하는 일이 알리는 것뿐이다. P1은 담당팀 멘션과 즉시 에스컬레이션, P2는 멘션과 티켓(1시간 내 대응), P3는 티켓만(다음 근무일), P4나 미확정은 스레드 종료. 잘못 눌러도 시스템이 안 망가지는 행위들이다.

2차 대응은 Pod 재시작, 롤백, 스케일 조정, 알럿 임계치 조정처럼 실제 상태를 바꾸는 일이라 Slack 승인 버튼을 거쳐야 한다. AI가 오판해서 멀쩡한 서비스를 롤백하는 사고를 구조적으로 차단한다.

담당자 개입 지점은 세 개다. Close Incident(종료), Re-analyze(재분석), 그리고 문제 해결 후에도 계속 울리는 알럿의 수동 종료.

실제 시나리오 둘

정상 케이스. service-a 배포 직후 service-b·c·d에서 타임아웃 알럿이 쏟아진다. 상관분석이 세 축 점수로 이들을 하나의 인시던트로 묶는다. RCA는 get_annotations로 service-a의 배포 기록과 최근 커밋을 확인해 deployment_change를 rule-in, 나머지를 rule-out 한다. P1 확정 후 Slack에 “원인: service-a 배포 / 영향: b·c·d / 대응: 롤백”이 근거 링크와 함께 올라간다.

모른다고 말하는 케이스. service-e API 지연이 커졌는데 Tempo 트레이스는 있고 Loki 로그가 수집되지 않았다. LLM 초안은 “다운스트림 의존성 문제”라고 했지만 가드레일이 직접 근거 부족을 잡아내 other로 강등하고 심각도를 미확정으로 남긴다. 보고 내용은 “1~2초 지연과 HTTP 500은 확인했으나 로그 근거를 확보하지 못했다. 추가 근거 필요”였다. 로그 수집 후 Re-analyze로 확정 승격이 가능하다.

두 번째 케이스가 이 시스템의 진짜 성과라고 생각한다. 맞히는 것보다 틀린 확신을 안 하는 게 어렵다.

운영하며 배운 것 3가지

근거 없는 확신이 제일 위험하다. LLM은 모르면 모른다고 하는 대신 그럴듯한 문장을 자신 있게 지어낸다. 장애 대응에서 이게 치명적인 이유는 담당자가 그 말을 믿고 움직이기 때문이다. AI가 “메모리 부족”이라고 하면 메모리를 늘리러 가는데 실제 원인이 DB 커넥션 고갈이면 20분을 날린다. 글쓴이는 차라리 AI가 아무 말도 안 했으면 나았을 상황이라고 짚는다. 잘못된 확신은 대응을 엉뚱한 방향으로 끌고 간다. 사람이 직접 대응할 때보다 오히려 더 위험할 수 있다는 것.

관측성 응답은 생각보다 크다. 로그·트레이스 조회 한 번이 수백 KB다. 두세 번이면 컨텍스트 창이 찬다. 그래서 개별 도구 결과에 크기 상한을 걸고 잘렸다는 표시를 붙였다. 이 표시가 없으면 AI가 잘린 데이터를 전부로 착각해 “에러 로그가 3건뿐이니 경미하다” 같은 오판을 한다. 최종 결론 입력은 원본 대신 신호 요약(메트릭 위반, 주요 트레이스, 의존성, 로그 유무)으로 압축했다.

부수 효과가 흥미롭다. 원본을 통째로 넣으면 양 많은 신호가 양 적은 신호를 밀어낸다. 로그가 10만 줄이고 메트릭이 5줄이면 시선이 로그에 쏠린다. 신호 계층별로 고르게 요약하니 Loki 로그가 드문 상황에서도 Prometheus와 Tempo 신호가 결론 입력에서 밀리지 않게 됐다.

라벨 차이가 큰 복병이다. 같은 서비스명인데 Prometheus 계열은 service_name, Tempo는 resource.service.name을 쓴다. Loki는 에러 레벨이 로그 본문 JSON이 아니라 구조화된 메타데이터에 들어 있기도 하다. 그러면 올바른 데이터 소스를 골랐는데도 빈손으로 돌아온다. 데이터는 멀쩡히 있는데 AI는 “해당 트레이스가 없다”고 결론낸다. 해결책은 화려하지 않다. 여러 tenant를 순회하는 Mimir 조회, Loki tenant 라벨 주입, cAdvisor 라벨 기준 안내 같은 데이터 소스별 조회 관습을 RCA 프롬프트에 하나하나 명문화해 나갔다.

성과와 다음 계획

  • 초기 알럿 노이즈의 **85~95%**를 실시간 차단
  • 평균 장애 식별 시간(MTTR) 50% 감소

앞으로는 error budget 소모 속도(burn rate)를 심각도 판단에 반영하고, 승인 경계 안의 자동 조치를 넓히고, 확정된 P1 리포트를 조직 지식으로 축적할 계획이라고 한다.

내 작업에 가져올 점

RAG 쪽에 세 교훈이 그대로 대응된다.

  • 근거 없는 확신 → 검색 결과가 부실할 때 생성 단계에서 지어내는 문제. 근거 문서 인용을 강제하고 인용이 실제 검색 결과에 있는지 사후 검증하는 구조가 Evidence Guardrail과 같은 발상이다
  • 응답 크기 → 청크를 몇 개, 얼마나 크게 넣을지의 문제. 특히 “양 많은 신호가 적은 신호를 밀어낸다”는 지적은 한 출처가 상위 검색 결과를 독점하는 상황과 같다. 출처별 쿼터를 두거나 요약해 넣는 식으로 대응
  • 라벨 차이 → Confluence·Jira·Slack을 함께 다루면 작성자 필드도 날짜 형식도 제각각이다. 색인 단계에서 통일하지 않으면 필터가 조용히 0건을 반환하고 “0건 = 정보 없음”으로 흘러가면 첫 번째 문제로 되돌아간다. 세 교훈이 사실 하나로 이어져 있다

NAC 이슈 대응에도 쓸 만한 건 방법론 쪽이다. 원인 후보를 미리 정해두고 하나씩 배제해 나가기, 하나 찾았다고 거기서 멈추지 않기, 근거가 없으면 “모르겠다”고 말하기. 결국 RAG든 장애 대응이든 여러 소스를 뒤져 근거를 모아 답을 만든다는 구조는 같다. 검색 쪽 정리는 임베딩 검색 방식 - dense·sparse·hybrid에 있다.

용어

  • SRE (Site Reliability Engineering): 구글에서 시작된 직군·방법론. 서비스 신뢰성을 소프트웨어 엔지니어링 방식으로 관리한다
  • RCA (Root Cause Analysis): 근본 원인 분석. 증상이 아니라 원인을 특정하는 작업
  • MTTR (Mean Time To Repair): 장애 발생부터 복구까지 걸린 평균 시간. 장애 대응 성숙도의 대표 지표
  • 관측성 (Observability): 시스템 내부 상태를 밖에서 나온 데이터만으로 파악할 수 있는 정도. 모니터링이 “정해둔 것을 지켜보는 것”이라면 관측성은 “예상 못 한 문제도 파고들 수 있는 상태”에 가깝다
  • LGTM-P 스택: Grafana Labs의 관측성 조합. Loki(로그)·Grafana(시각화)·Tempo(트레이싱)·Mimir(메트릭) + Pyroscope(프로파일링)
  • Alertmanager: Prometheus 계열의 알럿 라우팅·그룹화·억제 컴포넌트. 라벨 매칭 기반이라 의미나 의존 관계는 못 본다
  • PromQL / LogQL: 각각 Prometheus 메트릭, Loki 로그를 조회하는 쿼리 언어
  • Ruler: 알럿 규칙을 주기적으로 평가하는 컴포넌트. Mimir Ruler는 메트릭, Loki Ruler는 로그 담당
  • Span / Trace: 분산 추적에서 개별 작업 단위(span)와 요청 하나가 서비스들을 거쳐간 전체 경로(trace)
  • Tenant: 하나의 관측성 백엔드를 여러 조직·환경이 나눠 쓸 때의 격리 단위. 어느 tenant를 보느냐에 따라 같은 쿼리도 결과가 달라진다
  • cAdvisor: 컨테이너 리소스 사용량을 수집하는 에이전트. 쿠버네티스 컨테이너 메트릭의 표준 출처
  • MCP (Model Context Protocol): LLM이 외부 도구·데이터소스에 표준 방식으로 접근하게 해주는 프로토콜
  • 컨텍스트 창 (Context Window): LLM이 한 번에 입력받을 수 있는 토큰 총량
  • 환각 (Hallucination): LLM이 근거 없는 내용을 사실처럼 생성하는 현상. 이 글의 “근거 없는 확신”이 여기 해당한다
  • Human-in-the-Loop: 자동 파이프라인 중간에 사람의 판단·승인을 필수로 끼워 넣는 설계
  • Error Budget / Burn Rate: SLO에서 허용된 실패 여유분과 그 소모 속도. 같은 에러율이라도 예산을 빨리 태우면 더 급한 장애로 본다
  • 에스컬레이션 (Escalation): 정해진 시간·심각도 기준에 따라 상위 담당자·조직으로 대응을 넘기는 절차
  • 온콜 (On-call): 정해진 기간 동안 장애 알럿을 받고 즉시 대응할 당번