logo
|
Blog
    AI AutomationBackend & Infra

    Prometheus, Loki, LiteLLM, Langfuse로 만든 AI 기반 장애 분석 시스템

    서지호's avatar
    서지호
    May 26, 2026
    Prometheus, Loki, LiteLLM, Langfuse로 만든 AI 기반 장애 분석 시스템
    Contents
    전체 구조로그 수집: OpenTelemetry Collector와 Loki메트릭 수집: Prometheus와 GrafanaAlertmanager에서 AI 진단기로 연결K8S-DIAGNOSER가 수집하는 컨텍스트Langfuse로 LLM 진단 추적Slack thread에 진단 결과 남기기read-only 원칙앞으로 개선할 부분마무리알림이 울렸을 때, 사람이 처음 5분 동안 헤매는 시간을 줄이는 것.

    인프라를 NKS 중심으로 이전하면서 모니터링 시스템도 함께 정리했다. 기존에도 Prometheus, Grafana, Alertmanager는 있었다. 알림도 Slack으로 잘 왔다.
    하지만 실제 장애가 발생하면 운영자가 Grafana를 열고, Loki에서 로그를 찾고, Kubernetes 이벤트를 확인하고, 최근 배포 내역과 GitHub 코드를 직접 비교해야 했다.

    즉, 알림은 자동화되어 있었지만 원인 파악은 여전히 수동이었다.

    이번 작업의 목표는 장애 알림이 발생했을 때 관련 로그, 메트릭, Kubernetes 상태, 코드 컨텍스트를 자동으로 모으고, LLM이 1차 진단을 작성해 Slack thread에 남기는 시스템을 만드는 것이었다.

    전체 구조

    구성은 다음과 같다.

    구조도

    각 컴포넌트의 역할은 명확하게 나눴다.

    Prometheus: 메트릭 수집과 SLO 기반 알림

    Loki: Kubernetes Pod 로그 저장과 로그 기반 알림

    Alertmanager: 알림 라우팅

    K8S-DIAGNOSER: 알림 컨텍스트 수집과 AI 진단 요청 (자체 제작 파이썬 어플리케이션)

    LiteLLM: LLM gateway

    Langfuse: LLM 호출 trace 추적

    Slack: 운영자가 보는 최종 알림 채널

    중요한 점은 K8S-DIAGNOSER가 직접 문제를 고치지 않는다는 것이다. 이 서비스는 read-only 진단기다. Kubernetes 리소스를 수정하지 않고, kubectl exec도 하지 않는다. 장애 상황을 읽고, 정리하고, 원인 후보를 제시하는 역할만 한다.

    로그 수집: OpenTelemetry Collector와 Loki

    로그 수집은 OpenTelemetry Collector DaemonSet이 담당한다. 각 NKS 노드의 /var/log/pods/*/*/*.log를 읽고 Loki로 전송한다.

    Loki는 NCP Object Storage를 backend로 사용한다. 현재 보존 기간은 7일로 설정했다.

    장기 보관보다는 장애 분석과 최근 운영 이슈 추적에 초점을 맞췄다.

    수집 대상은 특정 앱만이 아니라 NKS 클러스터의 Pod 로그 전반이다.

    Loki 기반으로는 다음과 같은 알림을 만들었다.

    특정 서비스에서 error-like 로그가 5분 이상 발생

    5분 동안 error-like 로그가 일정 개수 이상 burst

    fatal, panic, traceback, OOMKilled 같은 치명적 로그 발생

    이렇게 하면 HTTP metric으로는 잘 드러나지 않는 애플리케이션 내부 오류도 Slack으로 알릴 수 있다.

    메트릭 수집: Prometheus와 Grafana

    메트릭은 kube-prometheus-stack을 사용했다.

    기본적인 Kubernetes 상태 외에도 서비스별 HTTP availability, error rate, latency p95/p99, restart count, Pod 상태 등을 본다.

    Grafana에는 여러 대시보드를 구성했다.

    NKS Overview

    Workload Health

    Service SLO

    Application Metrics

    NKS Logs

    Log Storage & Cost

    Alert Overview

    Grafana는 사람이 직접 들어가서 보는 화면이고, Alertmanager는 장애 발생 시 Slack으로 알려주는 경로다. K8S-DIAGNOSER는 이 둘 사이에 들어가서 “알림을 해석하는 계층” 역할을 한다.

    Alertmanager에서 AI 진단기로 연결

    Alertmanager는 기존 Slack 알림을 그대로 유지한다. 대신 서비스 장애 알림이 발생하면 webhook receiver를 통해 K8S-DIAGNOSER에도 같은 알림을 보낸다.

    K8S-DIAGNOSER가 처리하는 대표 알림은 다음과 같다.

    ServiceErrorLogsDetected

    ServiceErrorLogBurst

    ServiceFatalLogsDetected

    ServiceEndpointDown

    HTTPAvailabilitySLOBreach

    HTTPErrorRateFastBurn

    HTTPP95LatencySLOBreach

    HTTPP99LatencySLOBreach

    장애 알림이 들어오면 Diagnoser는 alert fingerprint 기준으로 중복 진단을 일정 시간 막는다.

    같은 장애에 대해 LLM 호출이 반복되면 비용도 낭비되고 Slack thread도 지저분해지기 때문이다.

    K8S-DIAGNOSER가 수집하는 컨텍스트

    Diagnoser는 알림 하나를 받으면 관련 정보를 여러 곳에서 모은다.

    Loki에서는 해당 namespace/service의 에러 로그와 fatal 로그를 가져온다. Prometheus에서는 5xx rate, latency, restart count, pod waiting reason 등을 가져온다.


    Kubernetes API에서는 Deployment image, Pod 상태, Event, Service, Endpoint 정보를 읽는다.


    GitHub에서는 서비스 매핑에 따라 앱 repo와 인프라 repo의 관련 파일을 읽는다.

    초기 매핑은 이런 식으로 구성했다. ( argocd 앱 이름 → 레포지토리 이름)

    nuvion-be-dev → NUV-BE

    leaders-dev → LCD-BE

    ops, ops-prod → OPS-MVP, OPS-FE

    pm-agent-dev → PAP-BE

    litellm → K8S-LITELLM

    langfuse → K8S-LANGFUSE

    이 컨텍스트를 하나의 JSON으로 구성한 뒤 LiteLLM에 전달한다. secret 값이나 token처럼 민감한 문자열은 제거한다.

    LiteLLM 호출에는 metadata를 함께 넣는다.

    {incident_id
    
    alertname
    
    namespace
    
    service_name
    
    severity
    
    fingerprint
    
    trace_project
    
    team_id }

    이 metadata는 Langfuse에서 trace를 볼 때 유용하다.
    어떤 장애에서 어떤 프롬프트가 나갔고, 어떤 응답이 돌아왔는지 추적할 수 있다.

    Langfuse로 LLM 진단 추적

    AI 진단 시스템을 운영하려면 “LLM이 무슨 말을 했는지”도 관찰 가능해야 한다. 그래서 LiteLLM callback을 통해 Langfuse에 trace를 남긴다.

    Langfuse에서는 다음을 확인할 수 있다.

    1.어떤 알림에서 LLM 호출이 발생했는지

    2.어떤 모델이 사용되었는지

    3.프롬프트와 응답이 무엇이었는지

    4.응답 시간이 얼마나 걸렸는지

    5. 비용과 token 사용량이 어느 정도인지

    이건 단순한 로그보다 중요하다. AI 진단의 품질을 개선하려면 나중에 실제 장애와 진단 결과를 비교해야 한다. Langfuse는 그 평가 데이터를 쌓는 역할을 한다.

    Slack thread에 진단 결과 남기기

    진단 결과는 기존 Alertmanager 알림 thread에 답글로 남긴다.

    운영자가 장애를 볼 때 원본 알림, AI 진단, 사람의 후속 조치를 한 thread에서 이어서 볼 수 있어야 하기 때문이다.

    진단 메시지는 다음 구조로 고정했다.

    1. 원인 후보 최대 3개

    2. 근거

    3. 바로 확인할 명령

    4. 권장 수정 방향

    5. 신뢰도

    예를 들면 이런 형태다.

    example message


    read-only 원칙

    이 시스템에서 가장 중요하게 둔 원칙은 read-only다.

    K8S-DIAGNOSER는 다음을 하지 않는다.

    1.Kubernetes 리소스 수정

    2.kubectl apply

    3.rollout restart

    4.secret 값 조회

    1. pod exec

    2. GitHub PR 생성

    3. 자동 수정

    장애 상황에서 AI가 직접 조치를 실행하는 것은 아직 위험이 크다. 특히 Kubernetes와 인프라 영역에서는 잘못된 자동 조치가 장애를 키울 수 있다.
    그래서 현재 단계에서는 운영자의 판단을 돕는 진단 도구로만 사용한다.

    얻은 효과

    가장 큰 효과는 장애 초기 탐색 시간이 줄었다는 점이다.

    이전에는 알림을 받으면 아래 작업을 사람이 직접 해야 했다.

    1.어떤 서비스인지 확인

    2.Grafana dashboard 열기

    3.Loki에서 namespace/service 필터링

    1. 최근 error 로그 확인

    2. Pod 상태와 Event 확인

    3. 최근 배포 image 확인

    4. 관련 repo에서 설정과 코드를 검색

    8 .원인 후보 정리

    지금은 이 중 상당 부분이 Slack thread에 자동으로 정리된다.
    운영자는 처음부터 모든 도구를 뒤지는 대신, AI가 제시한 원인 후보와 근거를 보고 어디부터 확인할지 결정할 수 있다.

    물론 AI 진단이 항상 정답은 아니다. 하지만 장애 초기에 “볼 만한 방향”을 빠르게 제시해주는 것만으로도 충분히 가치가 있다.

    앞으로 개선할 부분

    아직 할 일도 많다.

    첫째, structured logging 표준화가 필요하다. 서비스마다 로그 포맷이 다르면 Loki query와 AI 컨텍스트 품질이 떨어진다. level, message, trace_id, request_id, user_id, error_code 같은 필드를 표준화하면 훨씬 좋은 진단이 가능하다.

    둘째, 서비스별 SLO를 더 정교하게 잡아야 한다. 지금은 availability, error rate, latency 중심이지만, 서비스별로 중요한 지표는 다르다. 예를 들어 API 서버와 media server, crawler, LLM gateway의 정상 기준은 같을 수 없다.

    셋째, Langfuse 기반 진단 품질 평가가 필요하다. 실제 장애가 끝난 뒤 AI 진단이 맞았는지, 어떤 근거가 유용했는지 평가하면 프롬프트와 컨텍스트 수집 방식을 개선할 수 있다.

    넷째, runbook과 연결을 강화할 수 있다. AI가 단순히 일반적인 조언을 하는 것이 아니라, 우리 팀의 실제 운영 문서와 GitOps 구조를 기준으로 진단하게 만들면 실용성이 더 올라간다.

    마무리

    이번 시스템의 핵심은 AI를 “자동 복구 장치”로 쓰지 않았다는 점이다.
    대신 운영자가 장애를 이해하는 데 필요한 컨텍스트를 자동으로 모으고,
    첫 번째 문제 해결 방법을 제시하는데에 사용하였다.

    Prometheus는 메트릭을 보고, Loki는 로그를 저장하고, Alertmanager는 알림을 보낸다. K8S-DIAGNOSER는 이 신호들을 하나로 묶어 LiteLLM에 전달하고, Langfuse는 그 AI 호출을 추적한다.
    최종 결과는 Slack 안에서 운영자가 바로 볼 수 있다.

    결국 목표는 단순하다.

    알림이 울렸을 때, 사람이 처음 5분 동안 헤매는 시간을 줄이는 것.


    이 정도만 달성해도 운영 경험은 크게 달라진다.

    Share article
    Contents
    전체 구조로그 수집: OpenTelemetry Collector와 Loki메트릭 수집: Prometheus와 GrafanaAlertmanager에서 AI 진단기로 연결K8S-DIAGNOSER가 수집하는 컨텍스트Langfuse로 LLM 진단 추적Slack thread에 진단 결과 남기기read-only 원칙앞으로 개선할 부분마무리알림이 울렸을 때, 사람이 처음 5분 동안 헤매는 시간을 줄이는 것.

    플래드

    RSS·Powered by Inblog