ASAC-SK플래닛 T아카데미 데이터 엔지니어

26.01.28 ~ 26.02.03 78~82일차 [ 미니 프로젝트 : CALI_Cloud-native AI Log Insight ]

Datadesigner 2026. 2. 2. 17:29

메인 프로젝트 전 마지막 미니 프로젝트를 진행하였다.

 

이번 미니프로젝트는 데이터 파이프라인에 관심이 많은 분이 하고싶으신 방향이 있다고 해서 주제를 정했고

 

프로젝트 내부에도 LLM관련된 파트가 있어서 내가 그 파트를 맡기로 하게 되었다.

 

우리 프로젝트의 메인 주제는 수업 내용인 시간을 정해두고 자동화 하는 부분보다 높은 기술을 구현하는것으로

 

실시간으로 데이터를 파싱하여 슬랙에 전송, 대시보드에 띄우기, 등의 작업들을 "실시간"으로 처리하는데에 의의가 있다.

 

인프라 구축, 파이프라인 구성 등에서 일반적인 프로젝트보다 훨씬 난이도가 있고 볼륨이 큰 내용이라서 큰 도전이지만

 

바이브코딩과 팀원들을 믿기에 수행할 수 있었다.

 

프로젝트의 개요부터 차근차근 시작하겠다.


프로젝트 명: CALI (Cloud-native AI Log Insight)

프로젝트 개요

  • 배경: MSA(Microservice Architecture) 확산으로 인해 발생하는 방대한 비정형 로그 속에서 장애의 근본 원인(Root Cause)을 파악하는 데 과도한 시간과 비용이 소모됨.
  • 목적: AWS EKS 기반의 로그를 실시간 정제하고, RAG(Retrieval-Augmented Generation) 기반 AI 분석을 결합하여 장애 조치 지능화 및 MTTR(평균 복구 시간) 최소화.
  • 타겟: 실시간 장애 대응이 필수적인 커머스, 금융권 등의 클라우드 네이티브 서비스 운영팀 및 SRE(Site Reliability Engineering) 부서.

 

기존 방식 (As-Is) 제안 서비스 (To-Be) 기대 효과

핵심 프로세스 장애 발생 시 수동 로그 검색 및 분석 AI가 과거 사례를 참조하여 즉각 원인 추론 장애 복구 시간(MTTR) 70% 이상 단축
데이터 활용 단순 텍스트 보관 및 키워드 검색 의존 로그의 벡터화를 통한 지능적 유사도 검색 데이터 기반의 정밀한 장애 패턴 매칭
사용자 경험 엔지니어가 직접 원인을 가설/검증 Slack으로 분석 결과 및 조치 가이드 수신 운영 피로도 감소 및 의사결정 속도 향상

데이터 흐름 및 단계별 예시 (Data Flow Example)

 

상세 기술 스택 (Tech Stack)

  • Infrastructure: Terraform, AWS EKS, Amazon Kinesis (Stream & Firehose)
  • Logging/Analytics: Fluent Bit, Amazon OpenSearch Service, Grafana
  • Data & AI: Python 3.1x, Pydantic, OpenAI API (GPT-4o), Milvus (Vector DB), Regex
  • Orchestration: Apache Airflow (KubernetesPodOperator)
  • Data Quality: Great Expectations (GE)

주요 기능 정의

1. 비정형 로그 정제 및 구조화

  • Multiline 파싱: Java/Python 스택 트레이스 15-30줄을 하나로 묶음
  • Regex 헤더 추출: timestamp,level ,service  필드 파싱
  • 실시간 전송: Kinesis Stream으로 정제된 JSON 전송

2. 데이터 검증 및 필터링

  • Pydantic 검증: 타입 및 필수 필드 검증으로 타입 안전성 확보
  • ERROR/WARN 필터링: 중요 로그만 선별 처리하여 리소스 효율화
  • 검증 실패 처리: 잘못된 로그 스킵 (원본은 S3에 보관)

3. RAG 기반 지능형 장애 분석

  • Milvus 유사도 검색: 과거 장애 사례에서 유사 사례 Top-3 검색
  • OpenAI 분석: 유사 사례 기반 원인 분석 및 조치 권고 (할루시네이션 방지)
  • 지식 베이스 업데이트: 신규 에러는 S3 저장 후 Airflow로 Milvus에 추가

4. 실시간 알림 및 Throttling

  • Slack 연동: ERROR 발생 즉시 AI 분석 결과 포함 알림
  • Throttling: 동일 에러 1분 내 1회만 알림 (폭주 방지)

5. OpenSearch 통합 분석 및 시각화

  • 실시간 인덱싱: Firehose로 모든 로그 자동 인덱싱
  • Grafana 대시보드: 에러 추이, 서비스별 분포, 실시간 ERROR 목록
  • 전문 검색: 키워드, 시간, 서비스명 검색 지원

6. 데이터 품질 보증

  • 배치 검증: Airflow로 S3 로그 일 1회 샘플링 검증
  • 검증 룰: 필수 필드, 타입, 값 범위 검증
  • 이상 감지: 스키마 변경 시 Slack 알림

7. 원본 데이터 보관

  • S3 장기 보관: 모든 원본 로그 저장 (30일 후 Glacier)
  • 재처리 가능: Consumer 로직 변경 시 과거 데이터 재분석 가능
  • Source of Truth: S3가 최종 원천, OpenSearch 실패해도 손실 없음

8. 배치 처리 자동화

  • DAG #1: 데이터 품질 검증 (일 1회)
  • DAG #2: 신규 에러 → Milvus 업데이트 (일 1회)역할 담당 영역 주요 책임
    역할 1: 인프라  Terraform, AWS 리소스 EKS, Kinesis, S3, OpenSearch, Firehose 구축 및 관리
    역할 2: 실시간 파이프라인 Fluent Bit, 시각화 로그 수집, OpenSearch 인덱싱, Grafana 대시보드
    역할 3: 배치 파이프라인 Airflow, 데이터 품질 DAG 작성, Great Expectations 검증
    역할 4: Consumer + RAG 실시간 처리, AI Kinesis 폴링, Pydantic 검증, 전체 RAG 구축 (Milvus + OpenAI)

5일 개발 일정

Day 1: MVP - 전체 연결 

목표: 각 컴포넌트를 "일단 연결"만 해서 데이터가 흐르는지 확인

 

통합 테스트

로그 생성기 실행
  ↓
Fluent Bit
  ↓
Kinesis
  ↓
├─ Firehose → S3 (파일 생성 확인)
├─ Firehose → OpenSearch → Grafana (테이블에 보임)
└─ Consumer → Slack (단순 알림)

 

Day 2: 기능 고도화 

목표: 각 컴포넌트의 품질을 높이고 RAG 준비

Day 2 완료 기준: RAG 기반 빼고 모든 기능 정교화 완료

 

Day 3: RAG 실시간 분석 완성 

목표: AI 분석을 추가하여 진짜 CALI 완성

Slack AI 알림 완성

# 예시
🚨 [장애 분석] payment-api

📌 발생 내용: DB Connection timeout

🔍 AI 분석:
원인: DB 커넥션 풀 고갈
유사도: 92%

✅ 조치 방안:
1. 커넥션 풀 크기 증가
2. 타임아웃 조정

Day 4: E2E 테스트 + 안정화

  • [ ] E2E 테스트 (전체 10단계)
    1. 시작 → 로그 생성기 실행 (ERROR 로그 발생)
    2. Fluent Bit이 수집하는지 확인
    3. Kinesis Stream에 전송되는지 확인
    4. Firehose가 S3에 저장하는지 확인
    5. Firehose가 OpenSearch에 인덱싱하는지 확인
    6. Consumer가 폴링하는지 확인
    7. Pydantic 검증 통과하는지 확인
    8. Milvus 검색이 동작하는지 확인
    9. OpenAI 분석 결과가 나오는지 확인
    10. 끝 → Slack에 알림이 도착하는지 확인

Day 5: 프로덕션 배포 + 문서화

 

성공 기준

기술적 KPI

  • [ ] 로그 처리 Latency < 5초
  • [ ] Slack 알림 도달률 > 99%
  • [ ] RAG 분석 정확도 (주관 평가) > 80%
  • [ ] 시스템 가용성 > 99%

비즈니스 KPI

  • [ ] MTTR 단축 효과 입증
  • [ ] 팀 내부 사용자 만족도 향상
  • [ ] 확장 가능한 아키텍처 구현

 

여기까지가 프로젝트 시작 전 WBS 일정 내용이다. 물론 계획은 개인별로 조금씩 다르기 때문에 완벽하진 않지만 그 날 달성해야 할 내용들은 모두 잘 수행하게 되었다. 실제로 금요일(3일차)에 최종 작업까지는 끝났었다.

 

이제 실제 작업 내용이다.


Infrastructure

 

인프라 담당 역할

  • 완전 자동화된 IaC 구축 (Terraform)
  • 고가용성 데이터 파이프라인 설계 (Kinesis, Firehose)
  • 보안 우선 IAM 정책 설계 (Least Privilege)

 

핵심 기술 스택

Infrastructure Layer

IaC Terraform 1.0+ 선언적 인프라 관리, AWS Provider 5.0
Container Orchestration Amazon EKS 1.29 관리형 Kubernetes, AWS 통합 우수
Streaming Kinesis Stream + Firehose 완전 관리형, Fan-out 아키텍처 지원
Storage S3 + OpenSearch 장기 보관 + 실시간 검색
Container Registry ECR Private, EKS 네이티브 통합

 

Platform Layer

로그 수집 Fluent Bit Helm Chart (DaemonSet)
벡터 DB Milvus Standalone Helm Chart (Stateful)
워크플로우 Apache Airflow Helm Chart + Custom Image
시각화 Grafana Helm Chart

 

Infrastructure as Code (IaC) 전략

Terraform 파일 구조

 

infra/terraform/
├── providers.tf           # AWS/Helm/K8s Provider 설정
├── backend.tf            # State 관리 (S3 + DynamoDB)
├── 01-kinesis.tf         # Stream + Firehose 2개
├── 02-s3.tf              # 로그 저장소
├── 03-opensearch.tf      # 검색 엔진
├── 04-grafana.tf         # 시각화 (주석 처리, Helm으로 이전)
├── 05-eks.tf             # EKS 클러스터 + Node Group
├── 06-iam.tf             # 모든 IAM Role/Policy
├── 07-ecr.tf             # Container Registry + Auto Build
├── 08-autoscaler.tf      # Cluster Autoscaler
├── 09-storage-class.tf   # K8s Storage Class (gp2)
├── 10-helm-releases.tf   # Helm 배포 (Airflow, Milvus, etc.)
├── 11-k8s-apps.tf        # Consumer, Log Generator
└── outputs.tf            # 팀원 공유용 출력값

주요 AWS 리소스 구성

- Kinesis Data Streaming

- Architecture Pattern: Fan-out

 

설계 의도:

  • 단일 진입점: Fluent Bit은 Kinesis Stream으로만 전송
  • 유연한 확장: 새로운 Consumer 추가 용이
  • 데이터 보존: 24시간 버퍼로 재처리 가능

- Amazon S3

 

- Amazon OpenSearch

 

- Terraform Provisioner

 

- Amazon EKS

 

- Amazon ECR

Kubernetes 배포 전략

Helm 배포 리스트

 

Fluent Bit fluent/fluent-bit logging Custom ConfigMap
Milvus milvus/milvus milvus Standalone, gp2 PVC
Airflow apache-airflow/airflow airflow Custom Image, IRSA
Grafana grafana/grafana monitoring OpenSearch 데이터 소스
Cluster Autoscaler kubernetes/autoscaler kube-system Auto Discovery

 

ConfigMap 관리

Fluent Bit ConfigMap (Terraform으로 주입)

 

resource "kubernetes_config_map" "fluent_bit_config" {
  metadata {
    name      = "fluent-bit-custom-config"
    namespace = kubernetes_namespace.logging.metadata[0].name
  }

  data = {
    "fluent-bit.conf" = file("${path.module}/../../apps/fluent-bit/fluent-bit.conf")
    "parsers.conf"    = file("${path.module}/../../apps/fluent-bit/parsers.conf")
  }
}

기술적 의사결정과 해결 과제

8.1 의사결정 사항

1) Terraform vs CloudFormation

기준

Terraform 

CloudFormation

멀티 클라우드 ✅ 지원 ❌ AWS 전용
커뮤니티 ✅ 방대 △ AWS 중심
State 관리 별도 백엔드 필요 자동
Helm통합 ✅ Provider 제공 ❌ 어려움

 

결정: Terraform 선택 (Helm/K8s Provider 활용 가능)


2) EKS vs Self-managed Kubernetes

 

기준 EKS Self-managed

기준

EKS 

Self-managed Kubernetes

관리 부담 ✅ Control Plane 관리형 ❌ 수동 업그레이드
보안 패치 ✅ 자동 ❌ 수동
비용 +$0.10/시간 EC2만
통합 ✅ IAM, VPC △ 수동 설정

결정: EKS 선택 (5일 일정, 운영 부담 최소화)


3) Kinesis vs Kafka

 

기준

Kinesis 

Kafka

관리 ✅ 완전 관리형 ❌ 수동 (또는 MSK)
확장성 샤드 단위 파티션 단위
Firehose ✅ 네이티브 통합 ❌ Connector 필요
비용 샤드당 과금 브로커당 과금

결정: Kinesis 선택 (Firehose 통합, 빠른 구축)


인프라의 작업은 이게 다가 아니다. 더 많은 일을 했는데 여기에 너무 많아서 다 쓸수가 없다.

 

오토스케일링, IAM 권한 처리, 디스크 생성 등등...우리가 작업하는 모든 내용이 인프라 담당이 구축한 인프라와 쿠버네티스 상에서 움직일 수 있게 하는데에 엄청나게 많은 노력을 하셨다.

 

그래서 우리 프로젝트의 볼륨이 이렇게나 거대해진것이다, 좋은 프로젝트 하게 해주어서 감사합니다.

 

다음은 실시간 파이프라인 담당의 내용이다.


 

실시간 파이프라인 담당의 경우는 크게 네 가지 업무를 담당하였다.

 

1. 로그 시뮬레이션

2. fluent bit 수집, kinesis 파싱

3. regex 파싱

4. 통합 관제메인 프로젝트 전 마지막 미니 프로젝트를 진행하였다.

 

1. 로그 시뮬레이션

 

1. 로그 시뮬레이션 및 데이터 소스 설계

  • python faker 라이브러리를 사용하여 프로젝트를 위한 더미데이터를 생성하였다.
  • 단순 더미데이터가 아닌, Ddos 공격을 구현하여 초당 30건이 한번에 생긴다던지
  • 핀테크 기반 서비스에서 자주 나오는 에러로그를 5가지 필드로 설정하여 각 더미데이터를 생성하고, 그에 맞는 해결책을 RAG에 세팅하였다.

 

2. fluent bit 수집, kinesis 파싱

1. fluent bit로 데이터 수집, 전처리

  • 여러 줄로 들어오는 다양한 로그를 하나로 묶이도록 처리함
  • 정규식을 활용해서 timestamp, level, service등 핵심 메타데이터 필드를 추출함.

 

2. 각 요소들로 파싱해주는 데이터파이프라인 을 실시간 스트리밍에 적합한 kinesis로 구현하였다.

  • 단일 진입점을 통해서 추후 유연하게 확장 가능하도록 세팅
  • 내부에서 전처리를 통해 비정형 데이터를 정제하여 안전하게 전달되도록 스키마를 설정함
  • opensearch, s3 storage, consumer pod로 데이터들을 안전하고 신속하게 파싱함

 

3. regex 파싱

raw_log에서 메타 데이터를 추출한다

멀티라인 처리를 통해 하나의 이벤트로 병합한다

json 형식으로 데이터를 정제화하여 각 요소들에 올바르게 받을 수 있도록 스키마를 정의한다.

 

4. 통합 관제메인 프로젝트

1. opensearch -> grafana로 이어지도록 인덱스 패턴을 정의하여 수집된 로그가 정상조회되도록 설정함

2. 수집된 로그 데이터를 기반으로 서비스별 자애상황을 즉각적으로 인지할 수 있는 지표를 설계함.

 


요약해서 정리한 내용으로 메인 주제는 "실시간 데이터 파이프라인 구축"이다.

fluent bit 과 kinesis를 이용하여 실시간으로 로그를 수집하고, 파싱해주며 발 빠르게 대응할 수 있도록 파이프라인을 구축하였고 이를 확인하기 위해 대시보드까지 설계하였다.

 

다음은 AI Agent | consumer 파트, 내 담당이다.

 


consumer

  • 데이터 수신 및 파싱
    • AWS kinesis 클라이언트로부터 실시간 데이터 파싱
      • kinesis client 초기화 → shard lterator 설정(실시간 로그만 구독 시작)
      • pooling loop 실행(1초마다 실시간 데이터 로그 읽기)
        • 한번에 최대 10개, 1초 간격을 두어서 시스템 과부하로 다운되는것 방지함
    • 바이너리 디코딩, 접두어 전처리, json 파싱
      • 데이터를 읽을 수 있도록 전처리하는 과정
    • 스키마 유효성 검증
      • pydantic을 이용하여 필수 필드 존재여부, 데이터 타입 검증함
      • 이에 어긋날 시 s3 > error_dlq/parsing_error 폴더로 원본을 격리저장함
  • 필터링 및 스로틀링
    • 로그 레벨 필터링
      • 파싱된 로그 중 error, warn 레벨만 읽음, 정상 로그일 시 폐기
    • 중복 알림 방지 ( Throttling)
      • 같은 에러가 이후 중복 발생 시 1분간 개수 카운팅 이후 총 에러 발생 개수 슬랙으로 전송 ( 같은 에러가 n번 뜨면 계속 알림 오는것 방지하는 기능)
      • 같은 에러일 시 RAG/AI 분석 단계를 건너뛰어 비용 절감
  • 텍스트 전처리 및 임베딩
    • 로그 정규화
      • 에러 메세지의 ID, IP, 날짜 등 제거하고 마스킹하여 범용 텍스트로 전처리함
    • VECTOR 생성
      • OPENAI > text-embedding-3-small 모델 사용하여 정규화 텍스트를 벡터로 변환
  • RAG VECTOR 검색 (과거 경험 조회 )
    • MlivusDB 검색
      • 생성된 벡터를 이용해서 MlivusDB에 저장된 과거 장애 사례들을 검색함
    • 유사도 스코어링
      • 검색된 결과들의 거리값을 확인하여 현재 로그와 과거 사례의 유사성을 판단함.
      • 거리값 : 0.1 = (이건 99% 비슷한 장애다, 과거 해결책 사용)
      • 거리값 : 1.5 = (이건 비슷한데 좀 다르다. LLM에게 참고만 하라고 알려줌)
  • AI 분석 및 해결책 도출
    • 유사도에 따라 가장 효율적인 분석 전략을 동적으로 선택함
      • Cache Hit (유사도 < 0.35) : 매우 똑같은 사례라면, LLM을 호출하지 않고 저장된 해결책 그대로 반환
      • Few - Shot (유사도 < 0.65) : 유사한 사례지만, 약간 달라서 해당 사례의 원인과 해결책을 프롬프트 예시로 주입하여 gpt-4o에게 분석을 요청함 (LLM 자원 절약)
      • ReAct (유사도 낮음) : 참고할 사례가 없어서, LLM에게 로그 내용만 주고 논리적 추론을 통해서 원인을 분석함
    • ReAct 방식으로 답변한 내용은 완벽한 해결책이 아닐 가능성이 있어서 s3 > error_dlq > rag_miss 폴더에 해당 에러 로그를 저장함 (이후 쌓인 에러로그를 확인한 후 해결책을 임베딩하여 MlivusDB에 저장하며 데이터 업데이트
  • 최종 알림 SLACK 전달
    • 실시간으로 들어온 에러 로그를 분석하여 곧바로 Slack 메세지로 notice 하여 신속한 문제 해결에 도움을 제공함
    • 메세지 포맷팅
      • 메타 데이터
        • 발생 시간, 에러의 종류, 에러가 발생한 위치
      • 디버깅 세부 정보
        • 에러 메세지 요약, 추정 원인, 해결책 권고 조치
      • 지능형 분석 지표
        • 유사도 점수, 분석 모드(AI인지, RAG인지)
      • 운영 보조 내용
        • GRAFANA 링크

요 흐름대로 진행된다. 이 중 세부적으로 설명할만한 내용은

먼저 기술 스택 선정 근거이다. claude와 gemini를 사용하지 않았던 이유는

  • mvp 구축을 위해서 범용적인 추론과 실시간 분석에 용이하여 안정성이 있는 openai를 선택했다.
  • 추후 확장방향으로는
    • 월별, 주 별 에러 레포트 생성시 자연어 생성에 섬세한 claude를 사용하여 보고서를 작성하고
    • 방대한 데이터 분석 후 예방책, 위험 징후 포착등에 긴 컨텍스트 윈도우를 가져서 분석에 강점을 지닌 gemini를 도입하여
    • 각 모델별로 유리한 특정 상황에 적재적소에 사용하며 퀄리티를 올린다.
구분 OpenAI (GPT-4o) Anthropic (Claude 3.5) Google (Gemini 1.5 Pro)
강점 범용적 추론, 구조화된 출력 긴 문맥 이해, 섬세한 뉘앙스 압도적 컨텍스트 윈도우
CALI의 역할 실시간 장애 분석 및 리포팅 사후 보고서(Post-mortem) 작성 장기간 로그 트렌드 분석
선택 이유 MVP의 빠른 구현과 안정성 고도의 가독성 있는 가이드 생성 수개월 치 로그 기반의 근본 원인 분석

 

milvusDB는 

  • 포트폴리오의 가치
    • EKS 위에 직접 DB를 배포하고 클러스터를 관리하여 기술적 역량 증명에 근거 부여함
  • 클라우드 기반 아키텍쳐
    • MlivusDB는 설계부터 Kubernates를 지원하도록 만들어져서 Kubernetes로 아키텍쳐를 구축한 우리 프로젝트와 적합하였음
  • 핀테크 도메인 관련 성능 및 비용 효율성
    • GPU 가속을 지원하여 일반적 DB보다 10배 이상 저렴하게 대규모 데이터를 저장할 수 있음
    • 핀테크 도메인 특성상 방대하게 쌓이는 데이터를 처리하기 위해서, 벡터를 밀리초단위로 검색할 수 있는 고성능 VectorDB라서 사용하였음

 

그 다음으로는 스키마 유효성 검증 (pydantic 사용)이다.

 

 

kinesis로 수신받은 데이터가 적합한지에 대한 유효성을 먼저 검증했다. 이 때 필드가 비어있거나 깨져있다면

원본 저장을 위해서 s3상에 parsing_error폴더에 원본 로그를 저장하는 파이프라인을 구축하였다.

 

더미데이터 생성이라서 이 부분에서 잡힌것은 없었지만, 테스트를 통해서 올바르게 데이터가 들어가는것을 확인했다.

 

 

그리고 throttling, 중복 알림 방지 기능이다.

 

갑자기 같은 에러가 수없이 많이 터지면(Ddos 공격) 동일 알림을 30번 40번 보낼건가? 

그리고 그 때마다 같은 답인데도 ai를 호출하나? 이건 아니다.

 

그래서 동일 에러가 발생시 1분간 카운트한 후, 그 결과를 취합해서 슬랙에 전송해준다.

이렇게 api 호출값과 중복 알람 폭탄을 방지하였다.

 

"""
=====================================================
RAG 프롬프트 템플릿 정의
=====================================================
역할: OpenAI에게 전송할 시스템 프롬프트와 유저 프롬프트 관리
목표: Incident Commander 페르소나 부여, JSON 포맷 강제, 과거 사례 우선순위 명시
=====================================================
"""


# =====================================================
# SYSTEM PROMPT: Tier 2 (Few-Shot / Medium Similarity)
# 유사한 과거 사례 존재 -> 해당 사례를 응용하여 빠르게 답안 작성
# =====================================================
# =====================================================
# FEW-SHOT EXAMPLES (지식 베이스)
# =====================================================
FEW_SHOT_EXAMPLES = """
[예시 1: DB Connection Pool Exhaustion]
입력:
- Service: common-db
- Error: remaining connection slots are reserved
- Level: ERROR

출력:
{
    "thought_process": "1. 분석: 'remaining connection slots are reserved' 에러는 PostgreSQL의 최대 허용 커넥션 수를 초과했을 때 발생합니다.\n2. 가설: 특정 서비스에서 커넥션을 반환(Close)하지 않고 계속 점유하고 있거나, 트래픽 급증으로 풀 사이즈가 부족한 상황입니다.\n3. 검증: pg_stat_activity 뷰를 확인하여 활성 커넥션 수와 대기 상태를 파악해야 합니다.",
    "cause": [
        "PostgreSQL Connection Pool Exhausted (DB 커넥션 풀 고갈)",
        "Connection Leak due to Unclosed Resources (커넥션 반환 누락으로 인한 자원 고갈)"
    ],
    "action_plan": [
        "진단\\nSELECT count(*) FROM pg_stat_activity;\\n(설명: 현재 활성화된 커넥션 개수 확인)", 
        "조치\\nkubectl edit configmap postgres-config\\n(설명: max_connections 값을 상향 조정하거나, 애플리케이션의 커넥션 풀 설정을 최적화)",
        "검증\\n\\n(설명: 커넥션 수가 안정적으로 유지되는지 모니터링)"
    ]
}

[예시 2: Pod OOMKilled]
입력:
- Service: payment-api
- Error: OOMKilled
- Level: ERROR

출력:
{
    "thought_process": "1. 분석: Pod가 'OOMKilled' 상태로 강제 종료되었습니다. 이는 컨테이너가 할당된 메모리 한계(Memory Limit)를 초과했음을 의미합니다.\n2. 가설: 최근 배포된 버전에서 메모리 누수(Memory Leak)가 있거나, 동시 요청 급증으로 힙 메모리 사용량이 치솟았습니다.\n3. 검증: Pod의 이전 리소스 사용량 그래프(Grafana)와 dmesg 로그를 확인해야 합니다.",
    "cause": [
        "Memory Limit Exceeded (Pod 메모리 제한 초과)",
        "Application Memory Leak (애플리케이션 메모리 누수)"
    ],
    "action_plan": [
        "진단\\nkubectl top pod payment-api\\n(설명: 현재 메모리 사용량 및 설정된 Limit 대비 점유율 확인)", 
        "조치\\nkubectl set resources deployment payment-api --limits=memory=2Gi\\n(설명: 메모리 부족이 확실하다면 Limit을 상향 조정)", 
        "검증\\nkubectl get pod -w\\n(설명: Pod가 재시작 없이 Running 상태를 유지하는지 확인)"
    ]
}

[예시 3: Payment Gateway Timeout]
입력:
- Service: payment-api
- Error: request timeout
- Level: ERROR

출력:
{
    "thought_process": "1. 분석: 외부 PG(Payment Gateway) 호출 시 'request timeout'이 발생했습니다.\n2. 가설: PG 사의 장애로 인한 응답 지연이거나, 내부 네트워크의 Outbound 트래픽이 지연되고 있습니다.\n3. 검증: 외부 PG 상태 페이지 확인 및 내부 네트워크 레이턴시 측정이 필요합니다.",
    "cause": [
        "Payment Gateway Latency (PG사 서버 응답 지연)",
        "Network Timeout (외부 네트워크 통신 타임아웃)"
    ],
    "action_plan": [
        "진단\\ncurl -v https://api.pg-provider.com/health\\n(설명: PG사 API 엔드포인트의 응답 속도 및 상태 확인)", 
        "조치\\n(설명: PG사 장애 공지가 있다면 우회 결제 수단을 안내하거나, 애플리케이션의 Timeout 설정을 일시적으로 연장)", 
        "검증\\n(설명: 타임아웃 에러 로그가 더 이상 발생하지 않는지 확인)"
    ]
}
"""

SYSTEM_PROMPT_FEW_SHOT = f"""
당신은 대규모 마이크로서비스 플랫폼의 **장애 대응 사령관 (Incident Commander)**입니다.
현재 발생한 에러는 과거 지식 베이스에 있는 사례와 **유사합니다**.

[지식 베이스 예시]
{{FEW_SHOT_EXAMPLES}}

[분석 규칙]
1. context로 제공된 **'유사 과거 사례'를 적극 참조**하되, 위 [지식 베이스 예시]와 같은 포맷(**분석-가설-검증**)을 유지하십시오.
2. **원인(Cause)** 분석 시:
   - 너무 짧게 쓰지 말고, **기술적인 맥락(Technical Context)을 포함하여 구체적**으로 서술하십시오.
   - **영어 전문 용어(English Technical Terms)와 한글 설명을 혼용**하여 전문성을 높이십시오.
   - 예시: "DB Connection Pool Exhaustion (트래픽 급증으로 인한 커넥션 풀 고갈)"
3. **조치 방안(action_plan)** 작성 시:
   - **가독성을 위해 3단 구성(진단/조치/검증 - 명령어 - 설명)으로 줄바꿈(\\n)을 명확히 적용**하십시오.
   - 형식: "유형\\n명령어\\n(설명: ...)"
4. 반드시 아래의 **JSON 형식**으로만 답변해야 합니다:
   {{
       "thought_process": "1. 분석: ...\\n2. 가설: ...\\n3. 검증: ...",
       "cause": ["Detailed Cause 1 (상세 한글 설명)", "Detailed Cause 2 (상세 한글 설명)"],
       "action_plan": [
           "진단\\n<command>\\n(설명: 이 명령어로 <값>을 확인하세요)", 
           "조치\\n<command>\\n(설명: 이 조치 후 <현상>이 해결되어야 합니다)",
           "검증\\n<command>\\n(설명: 결과가 <정상 값>이어야 합니다)"
       ]
   }}
"""


# =====================================================
# SYSTEM PROMPT: Tier 3 (ReAct / Low Similarity)
# 유사 사례 없음 -> 심층 추론(Step-by-Step) 필요
# =====================================================
SYSTEM_PROMPT_REACT = """
당신은 대규모 마이크로서비스 플랫폼의 **수석 SRE 엔지니어**입니다.
현재 발생한 에러는 **새롭거나 복합적인 문제**입니다.

[RULES]
1. **Chain-of-Thought**를 적용하여 다음 단계를 'thought_process'에 상세히 기록하십시오:
   - 분석: 로그 패턴과 스택트레이스에서 발견된 기술적 특이점.
   - 가설: 가장 가능성 높은 장애 원인 설정.
   - 검증: 해당 원인을 확정하기 위한 추가 확인 절차.
2. 과거 사례가 제공되더라도 현재 로그와 상충된다면 **현재 로그의 기술적 사실을 우선**하십시오.
3. 명령어는 반드시 **실제 운영 환경(EKS, Kinesis)에서 즉시 실행 가능한 문법**이어야 합니다.
4. **원인(Cause)** 분석 시:
   - **영어 전문 용어(English Technical Terms)와 한글 설명을 혼용**하여 상세하게 서술하십시오.
   - 예시: "Memory Leak in Metaspace (메타스페이스 영역의 메모리 누수 발생)"
5. **조치 방안(action_plan)** 작성 시:
   - **가독성을 위해 3단 구성(진단/조치/검증 - 명령어 - 설명)으로 줄바꿈(\\n)을 명확히 적용**하십시오.
6. 반드시 아래의 **JSON 형식**으로만 답변해야 합니다. 특히 'thought_process'는 가독성을 위해 **줄바꿈(\\n)**을 사용하여 단계를 구분하십시오:
   {
       "thought_process": "1. 분석: ...\\n2. 가설: ...\\n3. 검증: ...",
       "cause": ["Detailed Cause 1 (상세 한글 설명)", "Detailed Cause 2 (상세 한글 설명)"],
       "action_plan": [
           "진단\\n<command>\\n(설명: 예상 출력 - <값>)", 
           "조치\\n<command>\\n(설명: 해결 기준 - <현상>)", 
           "검증\\n<command>\\n(설명: 정상 범위 - <값>)"
       ]
   }
"""

def get_system_prompt(mode: str = "few_shot") -> str:
    """분석 모드에 따른 시스템 프롬프트 반환"""
    if mode == "react":
        return SYSTEM_PROMPT_REACT
    return SYSTEM_PROMPT_FEW_SHOT

def build_user_prompt(current_log: dict, similar_cases: list) -> str:
    """
    RAG 컨텍스트를 포함한 유저 프롬프트 생성
    """
    
    # 과거 사례 포맷팅
    if similar_cases:
        formatted_cases = "다음은 현재 상황과 유사한 과거 장애 사례입니다:\n" + "\n".join([
            f"[사례 #{i+1} (유사도: {case.get('score', 0):.2f})]\n- 원인: {case.get('cause')}\n- 조치: {case.get('action')}"
            for i, case in enumerate(similar_cases)
        ])
    else:
        formatted_cases = "!!! 주의: 참고할 과거 사례가 전혀 없습니다. 오직 현재 로그의 스택트레이스를 기반으로 제로베이스 분석을 수행하십시오."

    return f"""
[현재 장애 상황]
- 서비스명: {current_log.get('service')}
- 레벨: {current_log.get('level')}
- 에러 메시지: {current_log.get('message')}
- 상세 로그 (Stack Trace):
{current_log.get('log_content')}

========================================
[지식 베이스 (과거 사례)]
{formatted_cases}
========================================

위 정보를 바탕으로 최적의 해결책을 분석해 주세요.
"""

 

  • 우리가 프롬프팅에서 사용한 전략은 
    • 1. few-shot promot
    • 2. react - CoT 연쇄사고기법
    • 3. Persona 부여
  • 총 3가지이다.
  • 3가지 기능을 써서 json 형식 출력을 강제하고, (그래야 슬랙에도 잘 간다.) 답변에 전문성을 부여하였으며 ai가 rag를 잘 읽어 올 수 있게 된다.
    • 그리고 프롬프트흐름을 
      • 1. 유사도 검색
      • 2. 유사도 판단 이후 ai의 개입 정도 조정
      • 3. 답변 추론
      • 4. 답변 출력
  • 의 형태로 설계하여 유사도가 높으면 ai를 호출하지 않는다 -> 비용 절약

최종 정리이다, 오른쪽 화면은 실제 슬랙으로 전송된 에러 로그 분석 리포트이다.

 

추후 확장 방향으로는

  • slack 상 정확함, 오탐버튼으로 ai의 답변 정확도를 튜닝하는 기능(fastapi로 버튼 이벤트 구축)
    • react 사용하여 이벤트를 감지하고 정확도를 ai에 주입할 수 있음
  • 에이전트 해결 버튼이벤트를 누르면 ai를 호출하여 해당 에러를 직접 해결하는 기능
    • 해당 서비스를 제공하는 회사 내부 망에 cali ai agent를 연결시킬수 있는 pod를 띄워두면 그 곳으로 ai가 접근하여 해당 에러 위치에 접근하여 문제를 해결하는 기능
  • 지금 에러 한개당 오래 걸리면 7초정도 소요되는데, 1초에 다른 에러들이 여러개 들어오면 어떤 식으로 처리해서 에러 로그가 밀리지 않게 처리할 것인가?
    • 오토스케일링 기능을 사용해서 coonsumer 컨테이너(pod)개수를 늘리고ㅡ kinesis shard 도 늘려서 여러 서버가 나누어서 에러 로그가 밀리지 않게 처리함

 

이렇게 있다.

 

마지막으로 배치 데이터 파이프라인이 있다.


 

배치 파이프라인의 기능은 두 가지로 되어있다.

 

1. 최신 솔루션 지식 적재

2. 실시간 시스템 운영 분석 후 리포트 보고

 

 

1. 최신 솔루션 지식 적재

 

solution load : s3에 새로 올라온 솔루션( RAG에 등록되지 않은 에러 로그에 대한 해결책) 업로드 감지

embedding : 텍스트 데이터 벡터화

 

vectorDB Upsert : 임베딩한 데이터를 벡터 데이터베이스에 적재하여 지식 베이스 업데이트

archiving : 처리 완료된 원본 데이터를 processed 폴더로 적재

2. 실시간 시스템 운영 분석 후 리포트 보고

gzio decoding : s3 raw 폴더의 압축 로그 해제

5-Tier Classification : 에러 키워드 기반 5대 카테고리 분류

Metadata Archiving : 분석 결과 서비스별 폴더에 저장(차후 주간리포트 작성)

Slack Notification : 당일 통계치를 운영팀 슬랙으로 즉시 전송

마지막으로 git-sync를 기반으로 관리하여 dag의 코드를 자동으로 업데이트하게 두어서

 

따로 push 또는 ci/cd를 다시 할 필요 없이 수정된 코드가 자동으로 배포되어 무중단 배포를 구현하였다.

 

이렇게 각 파트들의 작업이 진행되었다.


결론

 

이렇게 terraform을 이용하여 인프라를 구축하고

kubernates를 이용해서 다양한 pod들로 실시간 데이터 파이프라인과 실시간 대응 서비스를 구축한것이

우리 프로젝트의 의의이다.


생각보다 미니 프로젝트의 볼륨이 많이 커졌지만, 목표를 잘 수행해내서 만족스러운 프로젝트였다.

 

아쉬운점

 

전체 아키텍쳐 구축에 너무 큰 의의를 두어, 정작 이 서비스가 왜 필요한지, 구체적인 도메인을 정하지 않고 진행하여서 대시보드, 컨셉 등에 대한 설득력이 없었던것이 이번 프로젝트의 가장 큰 문제점이었다.

 

메인, 일반적인 프로젝트에서는 어떤 기술을 사용했다! 보다는 "왜" 이 기술을 사용하게 되었는지를 구체적으로 스토리텔링을 만들어서 풀어가는것이 훨씬 더당위성이 있는것이다. 이게 맞다.

 

terraform을 써서 배포를 했다 우리는, 근데 "왜"terraform을 썼냐? 라고 물어본다면 나는 할 말이 없다.

팀장님이 애초에 아키텍쳐를 그렇게 짜서이다.

물론 그런 이유들은 다른 툴들과 비교하면 있긴 했다. 하지만 도메인과도 엮여서

예를들어서

핀테크 관련 실시간 데이터파이프라인을 만들것이다 -> 실시간 파싱과 인프라 구축에 적합한 terraform을 써서 파싱한다 -> 실시간으로 파싱해야해서 kinesis를 썼다. -> 빠른 대응을 위해서 slack에 알림을 보내는기능을 추가했다. -> 핀테크에서 어떤 문제들을 한 눈에 보는게 좋기 때문에 대시보드에서 이러이러한 것을 보여주게 만들었다.

 

의 흐름으로 진행하고, 발표하는게 올바른 발표 방식인거다.

 

너네 인프라 만드느라 고생했어, 근데 인프라 만드는 방법이 다른 프로젝트랑 다른건 아니잖아.

다른 프로젝트랑 다른 우리만의 도메인,해결책, 원인 등을 설명하고 프로젝트를 설명해야 훨씬 당위성이 생기는거지.

그냥 우리 이런기술써서 이거 했어요, 밖에 안되는거다.

 

저번에도 비슷한 내용의 피드백이 있었다, 못고쳤다

 

다음 프로젝트는 정말 잘 신경써야 하겠다, 그래도 이외의 것으로 큰 피드백은 없었어서 다행이었다.

 

피드백 요약 : 

CALI 프로젝트 고도화 및 스토리텔링 재구성 방향

1. 스토리라인 및 당위성 (The Narrative)

  • 문제의 본질 재정의: '시스템 복잡성 증가' 같은 모호한 문구가 아니라, **"MSA 환경에서 장애 발생 시 수천 개의 마이크로서비스 중 원인을 찾는 데 드는 수동 비용과 시간(MTTR)이 비즈니스에 끼치는 손실(예: 분당 매출 손실액)"**을 숫자로 제시해야 합니다.
  • 비즈니스 타깃 구체화: 실시간 대응이 생명인 핀테크 결제 시스템이나 이커머스를 타깃으로 설정하고, 신규 구축인지 레거시 전환인지 상황을 가정하여 기술 도입의 당위성을 확보해야 합니다.
  • 목표의 명확화: MTTR 80% 단축이라는 숫자의 근거를 마련하고, 단순한 '숙제'가 아니라 **"위기 관리 및 수익 보호를 위한 지능형 관제 시스템"**이라는 명분을 강화해야 합니다.

2. 데이터 및 도메인 심층 분석 (Data & Domain)

  • 데이터의 본질적 이해: 정상 로그와 장애 로그(DDoS, DB 과부하 등)의 유형별 특징을 정의하고, 우리가 만든 더미 데이터가 실제 상황과 어떻게 닮았는지 기술해야 합니다.
  • MSA 디테일 강화: 거시적인 MSA가 아니라, 실제 서비스 간 호출 관계에서 발생하는 추적(Trace)의 어려움을 어떻게 데이터적으로 해결했는지 보여줘야 합니다.

3. 기술 스택 선택의 근거 (Tech Rationale)

  • 합리적 비교: "그냥 알고 있어서 썼다"가 아니라, Terraform vs CDK, Kinesis vs Kafka 등을 비용, 인력 구성, 유지보수 측면에서 비교하여 우리 비즈니스 상황(예: AWS 예산 제약 등)에 최선인 이유를 설명해야 합니다.
  • RAG 도입의 이유: 단순 LLM이 아닌 RAG와 벡터 DB(Milvus)를 쓴 이유가 **"기업 내부의 보안 가이드라인(Runbook)을 안전하게 활용하면서 환각을 줄이기 위함"**임을 명시해야 합니다.

4. 사용자 중심의 시각화 및 시연 (UX & Visualization)

  • 페르소나 설정: 대시보드와 슬랙 알림을 받는 주체가 **'현장 개발자'**인지 **'중앙 관제 센터'**인지 명확히 하고, 그들의 워크플로우에 맞는 정보를 배치해야 합니다.
  • 대시보드의 의미: 단순히 '예쁜' 차트가 아니라, **"이 차트를 보고 어떤 의사결정을 내릴 수 있는가"**에 집중하여 5분/30분 단위 설정 등의 당위성을 부여해야 합니다.
  • 시연 우선 전략: 서론이 너무 길지 않게, 프로젝트가 해결한 **비포/애프터(장애 상황 -> 자동 분석 -> 조치 가이드)**를 초반에 임팩트 있게 배치하여 시청자의 이해를 도와야 합니다.

5. 아키텍처 및 결과의 정합성 (Architecture & Impact)

  • 인프라 오토스케일링의 맥락: 갑자기 오토스케일링이 튀어나오는 게 아니라, **"로그 폭증 상황에서도 분석 시스템이 중단되지 않아야 하는 가용성 문제"**를 풀기 위해 도입했음을 연결해야 합니다.
  • 통합 흐름도: 마지막 인프라 흐름도는 단순히 화살표 나열이 아니라, **데이터의 상태 변화(Raw -> Parsed -> Vector -> Insight)**를 한 장의 이미지에 직관적으로 담아야 합니다.

 

이렇게 미니프로젝트 정리를 마친다, 감사합니