Dev SLI SLO 기준 - 100-hours-a-week/KTB4-2nd-Cloud GitHub Wiki

SLI/SLO 기준

V1의 주요 기능이 정상적으로 동작하는지 같은 기준으로 판단하기 위해 SLI/SLO를 구성했습니다. 운영 로그와 부하 테스트 결과를 이 기준에 맞춰 확인하고, 측정 결과가 쌓이면 목표값을 조정합니다.

현재 목표값은 운영 데이터가 충분히 쌓이기 전에 정한 초기 기준입니다.


측정 환경

다음 데이터가 CloudWatch에 수집됩니다.

데이터 확인할 수 있는 내용
Nginx JSON Access Log 요청 경로, 상태 코드, 전체 요청시간, Backend 응답시간
Backend JSON Log 로그인, 여행 생성, 원본 저장, AI 요청, 여행 조회의 성공/실패와 처리시간
AI JSON Log AI 작업 결과, 단계별 처리시간과 실패 지점
EC2/CloudWatch Agent Metric CPU, Memory, Disk, Network와 주요 Process 상태
flowchart LR
  subgraph APP["App EC2"]
    NG["Nginx<br/>Access, Error Log"] --> AG["CloudWatch Agent"]
    HOST["메모리, 디스크, 프로세스"] --> AG
    BE["Backend 컨테이너<br/>stdout JSON"]
  end
  subgraph WK["Worker EC2"]
    AI["AI 컨테이너<br/>stdout JSON"]
  end
  AWS["EC2 기본 지표<br/>CPU, 네트워크, 상태 검사"]
 
  AG -- "로그" --> CWL[("CloudWatch Logs")]
  AG -- "지표" --> CWM[("CloudWatch Metrics")]
  BE -- "awslogs 드라이버" --> CWL
  AI -- "awslogs 드라이버" --> CWL
  AWS --> CWM
 
  CWL --> Q["Logs Insights<br/>request_id, trip_id, job_id"]
  CWL --> D["Dashboard<br/>yeodam-v1-operations"]
  CWM --> D
Loading

Dashboard yeodam-v1-operations에서 요청 현황, Backend와 AI의 결과와 지연시간, 최근 실패와 Host 상태를 한 화면에서 봅니다.

개별 요청이나 작업의 원인은 Logs Insights에서 request_id, trip_id, job_id로 검색합니다.


핵심 SLI와 초기 SLO

기능 성공 기준 SLI 초기 SLO 지연시간 기준
카카오 로그인 인증 처리 후 서비스 또는 신규 사용자 등록 화면으로 이동 로그인 성공 건수 / 유효한 로그인 종료 건수 99% 이상 Backend 처리 p95 3초 이하
여행 생성 요청한 원본이 모두 보존되고 AI 결과가 여행에 반영됨 여행 생성 성공 건수 / 여행 생성 종료 건수 99% 이상 Upload Batch 구간 분리 후 확정
AI 처리 Backend가 요청한 작업이 최종 성공함 AI 작업 성공 건수 / AI 작업 종료 건수 95% 이상 전체 처리 p95 30분 이하
완료 여행 조회 완료된 여행의 필수 사진, 장소, 경로가 반환됨 조회 성공 건수 / 유효한 조회 종료 건수 99% 이상 Backend 처리 p95 1초 이하

started 로그는 작업 시작을 추적하는 보조 이벤트입니다. 성공률에는 success, failure처럼 결과가 확정된 종료 이벤트만 사용합니다.


성공과 제외 기준

카카오 로그인

구분 기준
✅ 성공 인증이 끝나고 서비스 또는 신규 사용자 등록 화면으로 이동
❌ 실패 Callback, Token, 내부 처리 오류로 로그인을 완료하지 못함
➖ 제외 사용자가 직접 취소한 로그인, 잘못된 형식의 요청

Backend의 auth_login 이벤트로 서버 처리 결과와 시간을 측정합니다. 브라우저 Redirect와 화면 진입까지 포함한 전체 흐름은 FE E2E 테스트로 확인합니다.

여행 생성

구분 기준
✅ 성공 여행 정보가 저장되고 요청한 원본 수와 S3 저장 수가 일치하며 AI 결과가 반영됨
❌ 실패 원본 일부 누락, DB와 S3 불일치, AI 작업 등록 또는 결과 반영 실패
➖ 제외 파일 형식, 개수, 용량 제한을 정상적으로 거부한 요청, 사용자 취소

원본 사진 유실은 허용 실패율과 관계없이 바로 확인해야 하는 데이터 무결성 문제로 봅니다.

FE는 사진을 최대 10장 단위로 나눠 보냅니다. BE는 중간 Batch에서는 사진을 저장한 뒤 바로 응답하고, 마지막 Batch에서는 전체 저장을 확인한 뒤 AI 분석과 결과 저장까지 끝내고 응답합니다.

sequenceDiagram
  participant FE
  participant BE as Backend
  participant S3
  participant AI as AI Worker

  loop 중간 Batch (최대 10장씩)
    FE->>BE: 사진 업로드
    BE->>S3: 원본 저장
    BE-->>FE: 204
  end
  FE->>BE: 마지막 Batch
  BE->>S3: 원본 저장, 전체 수 확인
  BE->>AI: 분석 요청
  AI-->>BE: 분석 결과
  BE-->>FE: 200
Loading

그래서 사진 업로드 시간과 AI 처리 시간은 나눠서 측정합니다.

AI 처리

구분 기준
✅ 성공 요청된 작업이 완료되고 결과가 Backend에 반영됨
❌ 실패 최종 실패, 제한시간 초과, Callback 실패 또는 작업 유실
⏳ 진행 중 목표 시간 안에서 대기하거나 실행 중인 작업

Worker EC2 시작과 컨테이너 준비 시간도 사용자가 기다리는 AI 처리 시간에 포함합니다. 단계별 병목은 ai_pipeline_step으로 따로 봅니다.

완료 여행 조회

구분 기준
✅ 성공 소유자가 완료된 여행을 조회하고 화면에 필요한 사진, 장소, 경로를 받음
❌ 실패 5xx, Timeout, 완료 상태인데 필수 결과가 빠진 경우
➖ 제외 존재하지 않는 여행, 권한 없는 접근, 아직 처리 중인 여행의 정상 응답

로그 이벤트와 계산 기준

Service Event 용도
Backend auth_login 로그인 성공률과 처리시간
Backend trip_creation 여행 생성 최종 결과
Backend photo_originals_saved 예상 원본 수와 저장 수 비교
Backend ai_job Backend 쪽에서 본 AI 요청과 완료 결과
Backend worker_ready Worker 준비시간
Backend trip_view 완료 여행 조회 성공률과 처리시간
AI ai_job AI API가 받은 작업의 최종 결과
AI ai_worker_execution Worker 실행 결과
AI ai_pipeline_step 단계별 처리시간과 실패 위치
AI ai_callback Backend 결과 전달 성공 여부
지표 계산식
로그인 성공률 auth_login 성공 / auth_login 종료 결과
여행 생성 성공률 trip_creation 성공 / trip_creation 종료 결과
원본 보존율 saved_count 합계 / expected_count 합계
AI 완료율 ai_job 성공 / ai_job 종료 결과
여행 조회 성공률 trip_view 성공 / trip_view 종료 결과

성공률만 보지 않고 전체 건수를 같이 봅니다. V1처럼 요청이 적을 때는 한두 건의 실패가 비율을 크게 바꾸기 때문입니다.


지연시간을 보는 위치

Nginx와 애플리케이션 로그의 시간은 재는 구간이 다릅니다.

Client ── Request Body 전송 ──▶ Nginx ──▶ Backend ──▶ (MySQL, S3, AI) ──▶ 응답

|◀─────────────────────── request_time ───────────────────────▶|
                                 |◀──── upstream_response_time ────▶|
                                           |◀─ duration_ms ─▶|
필드 측정 범위
request_time Client가 Request Body를 보내는 시간까지 포함한 전체 요청시간
upstream_response_time Nginx가 Backend에 요청을 넘긴 뒤 응답을 받기까지의 시간
duration_ms Backend 또는 AI가 기록한 업무 처리시간

업로드가 느릴 때 request_time만 길면 Client 네트워크나 파일 전송부터 확인합니다.

upstream_response_time과 Backend duration_ms도 같이 길면 App, MySQL, S3 처리 구간을 확인합니다.


지원 지표

아래 항목은 SLO 계산에 들어가지 않고, 실패 원인과 자원 한계를 찾을 때 씁니다.

대상 지표
App EC2 CPU, CPU Credit, Memory, Swap, Disk, I/O Wait, Network
App Process Nginx, MySQL, Docker 실행 여부와 사용량
Worker EC2 CPU, Network, Instance 상태와 Worker 준비시간
Nginx 경로별 요청 수, 5xx, request_time, upstream_response_time
Container Health, 비정상 재시작, Exit Code, OOM, 배포 Release

Error Budget

SLO 허용 실패율 평가 기간
99% 1% 30일
95% (AI 처리) 5% 30일

요청이 적으면 비율만 보지 않고 실패 건수와 주간 추세를 같이 봅니다.

⚠️ 원본 사진 유실, 복구할 수 없는 데이터 불일치, 보안 문제는 Error Budget으로 허용하지 않습니다.


부하 테스트 판정 기준

항목 판정선
HTTP 오류 유효 HTTP 요청의 5xx와 Timeout 비율 1% 미만
지연시간 로그인과 완료 여행 조회 p95가 초기 목표 이내
데이터 원본 사진 누락 0건
AI AI 작업 유실 0건, 테스트 종료 후 대기 작업 감소
안정성 컨테이너 비정상 재시작과 OOM 0건
저장 공간 Filesystem 사용률 80% 미만
회복 부하 종료 후 CPU, Memory, 응답시간이 정상 범위로 회복
flowchart LR
  B["Baseline<br/>기능, 측정 경로 확인"] --> P["Peak<br/>예상 최대 부하"]
  P --> S["Spike<br/>급증 후 회복"]
  S --> A["AI 처리량<br/>처리 경계 확인"]
Loading
단계 확인 목적
Baseline 적은 부하에서 기능과 측정 경로가 정상인지 확인
Peak V1 예상 최대 부하에서 오류율과 지연시간 확인
Spike 짧은 요청 급증 후 실패와 회복시간 확인
AI 처리량 작업 유입보다 처리가 느려지는 경계 확인

테스트마다 시작과 종료 시각, 동시 사용자 수, 사진 수와 크기, Cloud Commit, FE/BE/AI Release를 기록해서 같은 조건끼리 비교합니다.

실제 사용자나 팀원의 디버깅과 겹칠 수 있으면 별도 Runtime과 Test Data를 씁니다. Subdomain만 나눠서는 부하가 분리되지 않습니다.

실행 결과는 부하 테스트에 있습니다.

⚠️ **GitHub.com Fallback** ⚠️