8분

SLA 준수를 정확하게 추적하는 웹 앱을 구축하는 방법

SLA 준수를 추적하는 웹 앱을 설계·구현하는 방법: 지표 정의, 이벤트 수집, 계산 로직, 위반 알림, 정확한 보고 및 감사 가능성 확보 방법을 설명합니다.

SLA 준수를 정확하게 추적하는 웹 앱을 구축하는 방법

SLA 준수 정의와 당신이 만들려는 것

SLA 준수는 서비스 수준 협약(SLA)—제공자와 고객 간의 계약—에 명시된 측정 가능한 약속을 충족하는 것을 의미합니다. 이 앱의 역할은 증거를 가지고 간단한 질문에 답하는 것입니다: 이 기간 동안, 이 고객에 대해 우리가 약속한 것을 지켰는가?

세 가지 관련 용어를 분리하면 도움이 됩니다:

  • SLI(서비스 수준 지표): 원시 측정치(예: “성공 체크 비율”, “첫 응답 시간”, “서비스 복구 시간”).
  • SLO(서비스 수준 목표): SLI에 대한 내부 목표(종종 SLA보다 더 엄격함). 예: “99.95% 가동 목표.”
  • SLA: 외부에 합의된 약속으로 보상/벌칙과 연결되는 경우가 많음. 예: “월별 99.9% 가용성.”

자주 트래킹하는 SLA 지표

대부분의 SLA 추적 웹앱은 운영 데이터에 매핑되는 소수의 지표로 시작합니다:

  • 가동 시간/가용성: 보고 기간 동안 서비스가 “동작”한 비율
  • 응답 시간(지원): 고객 티켓 생성부터 최초 사람 응답까지의 시간
  • 해결 시간: 인시던트/티켓 생성부터 종료 또는 복구까지의 시간
  • 가용성 창: “영업시간만 카운트”, “예정된 점검 제외”, “고객 시간대 기준 08:00–18:00만 측정” 같은 규칙

누가 앱을 쓰고 왜 쓰나

서로 다른 사용자는 같은 진실을 다르게 보길 원합니다:

  • Ops/SRE: 위반을 조기 탐지하고 인시던트 타임라인을 검증
  • 지원팀: 고객별 응답·해결 약속 추적
  • 매니저: 추세, 위험, 팀의 목표 달성 여부 확인
  • 고객: 투명한 보고(때로는 상태 페이지)를 통해 발생한 일을 확인

당신이 만드는 것(그리고 만들지 않는 것)

이 제품은 추적, 증거, 보고에 관한 것입니다: 신호 수집, 합의된 규칙 적용, 감사 친화적 결과 생성. 성능을 보장하는 것이 아니라—정확하고 일관되게 측정하여 나중에 방어할 수 있게 만드는 도구입니다.

요구사항: 지표, 규칙, 이해관계자

테이블을 설계하거나 코드를 작성하기 전에, 당신의 비즈니스에서 “준수”가 무엇을 의미하는지 고통스럽게 명확히 하세요. 대부분의 SLA 추적 문제는 기술 문제가 아니라 요구사항 문제입니다.

입력 항목 수집(기억에 의존하지 말 것)

신뢰의 출처를 먼저 수집하세요:

  • 고객 계약 및 MSA(첨부 문서와 티켓 관련 부속서 포함)
  • 서비스 티어(예: Basic vs Premium)와 각 고객의 매핑
  • 고객(또는 서비스)별 영업시간과 시간대
  • 제외 및 특별 규칙: 예정된 점검 창, 불가항력, 고객 원인 지연, 서드파티 의존성, 유예 기간

이 규칙들을 명시적 규칙으로 문서화하세요. 규칙이 명확히 서술될 수 없다면 신뢰성 있게 계산할 수 없습니다.

무엇을 추적해야 하는지 결정

SLA 수치에 영향을 줄 수 있는 실제 “사물”을 나열하세요:

  • 인시던트/중단(시작, 종료, 심각도, 영향받은 서비스)
  • 요청/티켓(생성, 최초 응답, 해결, 고객 대기 상태)
  • 점검(예정 vs 긴급; 가용성에 포함되는지 여부)
  • 부분 중단(성능 저하)과 그것이 카운트되는지 여부

또한 누가 무엇을 필요로 하는지도 식별하세요: 지원팀은 실시간 위반 위험을 원하고, 매니저는 주간 집계, 고객은 상태 페이지용 간단한 요약을 원합니다.

첫 릴리스에 1–3개 지표 선택

범위를 작게 유지하세요. 시스템이 엔드투엔드로 작동함을 증명할 최소 집합을 선택하세요. 예:

  • 서비스별 월별 가용성 %
  • 영업시간 내의 인시던트 응답 시간(첫 사람 응답)
  • 심각도-1 인시던트의 해결 시간

요구사항 체크리스트 및 성공 기준

나중에 테스트할 수 있도록 한 페이지 체크리스트를 만드세요:

  • 명확한 지표 정의(시작/종료 타임스탬프, 시간대, 반올림)
  • 포함/제외 규칙(점검, 고객 대기 시간)
  • 티어별 목표 임계값(예: 99.9%, 1시간 응답)
  • 출력 요구사항(고객 보고서, 내부 대시보드, 내보내기)

성공은 두 사람이 샘플 월을 수동으로 같은 방식으로 계산했을 때 당신의 앱이 정확히 동일한 결과를 내는 것입니다.

SLA, 서비스, 인시던트 및 이벤트를 위한 데이터 모델

올바른 SLA 트래커는 수치가 왜 그런지를 설명할 수 있는 데이터 모델에서 시작합니다. 월별 가용성 수치를 정확한 이벤트와 사용된 규칙으로 추적할 수 없다면 고객 분쟁과 내부 불확실성과 싸우게 됩니다.

핵심 엔터티(지루하고 명시적으로 유지)

최소한 다음을 모델링하세요:

  • Customer(고객/테넌트/계정): 서비스, 캘린더, 연락처, 보고 설정을 소유
  • Service(서비스): 측정 대상(API, 웹앱, 리전별 컴포넌트). 롤업이 필요하면 부모/자식 관계 옵션 포함
  • Plan(플랜): 상업적 래퍼(예: “Gold”), 기본 SLA 정책 세트를 연결하는 용도
  • SLA policy(정책): 가용성 목표, 응답 시간 목표, 측정 창, 제외 규칙 등
  • Incident(인시던트): 제목, 심각도, 타임라인 등 인간 친화적 그룹화로서 기반 이벤트를 참조
  • Event(이벤트): 계산을 구동하는 불변 사실(상태 변경, 모니터링 신호, 확인 등)

유용한 관계는: customer → service → SLA policy(플랜을 통해 연결될 수 있음). 인시던트와 이벤트는 서비스와 고객을 참조합니다.

시간 기반 추적을 위한 최소 스키마

시간 관련 버그는 잘못된 SLA 산출의 1순위 원인입니다. 다음을 저장하세요:

  • occurred_atUTC(타임존 의미 포함)로 저장
  • received_at(시스템이 이벤트를 본 시각)
  • source(모니터 이름, 통합, 수동)
  • external_id(중복 방지용)
  • payload(향후 디버깅용 원시 JSON)

또한 customer.timezone(예: America/New_York 같은 IANA 문자열)은 표시와 영업시간 로직에 사용하되 이벤트 시간을 덮어쓰지 마세요.

영업시간과 공휴일

응답 시간 SLA가 영업시간 외에 일시 중지된다면 캘린더를 명시적으로 모델링하세요:

  • working_hours 고객(또는 지역/서비스)별: 요일 + 시작/종료 시간
  • holiday_calendar 지역 또는 고객에 연결된 날짜 범위와 라벨

운영팀이 배포 없이 공휴일을 업데이트할 수 있도록 규칙을 데이터 기반으로 유지하세요.

감사 가능성: 원시 vs 계산 결과

원시 이벤트는 append-only 테이블에 저장하고, 계산된 결과는 별도로 저장하세요(예: sla_period_result). 각 결과 행에는 기간 경계, 입력 버전(정책 버전 + 엔진 버전), 사용된 이벤트 ID 참조를 포함해야 합니다. 이렇게 하면 재계산이 안전하고 고객이 “어떤 중단 분을 계산했나?”라고 물어볼 때 근거를 제시할 수 있습니다.

이벤트 수집: 데이터가 앱으로 들어오는 방법

SLA 수치는 수집하는 이벤트의 신뢰성에 달려 있습니다. 목표는 단순합니다: 중단 시작, 인시던트 확인, 서비스 복구 같은 중요한 모든 변화를 일관된 타임스탬프와 계산에 필요한 맥락과 함께 캡처하세요.

일반적인 이벤트 소스

대부분의 팀은 다양한 시스템에서 가져옵니다:

  • 티켓/인시던트 도구(Jira Service Management, ServiceNow, Zendesk): 생성/확인/해결 타임스탬프, 우선순위 변경, 담당자 변경
  • 모니터링 도구(Pingdom, Datadog, CloudWatch, Prometheus Alertmanager): up/down 신호, 알람 발동/해제, 합성 체크 결과
  • 인프라/애플리케이션 로그: 배포 이벤트, 에러 급증, 헬스 체크 실패(모니터링이 시끄럽거나 누락된 경우 유용)
  • 수동 입력: 자동화로 알 수 없는 사실을 위해 “비즈니스가 확인한 중단 시작/종료” 또는 “점검 창 시작”을 입력하는 작은 UI

수집 방식(언제 무엇을 쓸지)

웹후크는 실시간 정확성과 낮은 부하 때문에 보통 최선입니다: 소스 시스템이 당신의 엔드포인트로 이벤트를 푸시합니다.

폴링은 웹후크가 없을 때 좋은 대안입니다: 앱이 마지막 커서 이후 변경사항을 주기적으로 가져옵니다. 속도 제한 처리와 정확한 “since” 로직이 필요합니다.

CSV 임포트는 백필 및 마이그레이션에 유용합니다. 이 경로를 1등 시민으로 취급하여 이력 기간을 재처리할 때 해킹이 필요 없게 하세요.

권장 이벤트 포맷(멱등성 포함)

상류 페이로드가 달라도 내부적으로는 단일 이벤트 형태로 정규화하세요:

  • event_id(필수): 재시도 간에도 고유하고 안정적. 소스 GUID를 우선 사용하거나 결정적 해시 생성
  • source(필수): 예: datadog, servicenow, manual
  • event_type(필수): 예: incident_opened, incident_acknowledged, service_down, service_up
  • occurred_at(필수): 이벤트가 발생한 시각(수신 시각이 아님), 타임존 포함
  • received_at(시스템): 앱이 수신한 시각
  • service_id(필수): SLA 관련 서비스
  • incident_id(선택 권장): 여러 이벤트를 하나의 인시던트로 연결
  • attributes(선택): 우선순위, 지역, 고객 세그먼트 등

event_id에 고유 제약을 두어 멱등성(idempotency)을 확보하세요: 재시도는 중복을 만들지 않습니다.

잘못된 데이터를 막는 검증 규칙

다음과 같은 이벤트는 거부하거나 격리하세요:

  • 누락되었거나 잘못된 타임스탬프, 혹은 미래로 지나치게 벗어난 occurred_at
  • 알려진 service_id로 매핑되지 않은 경우(또는 명시적 “미매핑” 워크플로 요구)
  • 이미 존재하는 event_id와 중복되는 경우
  • 규칙을 깨는 순서 불일치로 도메인 로직을 훼손하는 도착(이 경우 “검토 필요”로 표시하고 자동 덮어쓰지 말 것)

이러한 규율은 나중에 SLA 보고서로 다투는 일을 줄여줍니다—왜냐하면 깨끗하고 추적 가능한 입력을 가리킬 수 있기 때문입니다.

SLA 계산 엔진: 이벤트를 준수 결과로 전환

계산 엔진은 원시 이벤트를 방어할 수 있는 SLA 결과로 바꾸는 곳입니다. 핵심은 회계처럼 다루는 것입니다: 결정론적 규칙, 명확한 입력, 재생 가능한 트레일.

정규화된 타임라인부터 시작

모든 것을 인시던트별(또는 서비스 영향별)로 단일 정렬된 스트림으로 변환하세요:

  • 타임스탬프(UTC): 인시던트 시작, 확인/첫 응답, 완화, 해결, 재개
  • 상태 변경: 일시중지/재개, 고객 대기, 점검 창 활성화
  • 범위: 어떤 서비스/고객이 어떤 심각도로 영향받았는지

이 타임라인에서 구간을 합산해 지속시간을 계산하세요. 두 타임스탬프를 무턱대고 빼지 마세요.

첫 응답 시간(TTFR) 및 해결 시간(TTR)

TTFR을 incident_startfirst_agent_response(또는 SLA 문구에 따라 acknowledged) 사이의 경과한 “청구 대상” 시간으로 정의하세요. TTR은 incident_startresolved 사이의 청구 대상 시간입니다.

“청구 대상”이란 아래와 같은 구간을 제거한 시간을 의미합니다:

  • 영업시간 외(영업시간 전용 SLA의 경우)
  • 일시중지 구간(예: “고객 대기”)
  • 점검 같은 제외 항목

구현 세부: 영업시간·공휴일을 처리하는 캘린더 함수와 타임라인을 받아 청구 대상 구간을 반환하는 규칙 함수를 저장하세요.

부분 중단과 다중 서비스 인시던트

사전에 다음 중 어떤 방식으로 계산할지 결정하세요:

  • 서비스별 SLA 계산(권장): 하나의 인시던트가 여러 서비스에 영향을 주면 각 서비스별 영향 기록을 생성하여 TTFR/TTR을 별도 계산
  • 고객별 SLA: 같은 중단이 일부 테넌트에만 영향 줄 수 있음

부분 중단은 계약에서 가중치를 요구하지 않는 한 별도 위반 카테고리로 처리하거나, 계약 요구사항에 따라 영향 가중치를 적용하세요.

추적성: 입력, 출력, 재생 저장

모든 계산은 재현 가능해야 합니다. 다음을 영구 저장하세요:

  • 사용된 정확한 이벤트(IDs, 타임스탬프, 소스)
  • 파생된 구간(무엇이 왜 제외되었는지)
  • 최종 결과(TTFR, TTR, 위반 플래그, 규칙 버전)

규칙이 변경되면 버전별로 재실행할 수 있어야 하며, 이력은 덮어쓰지 마세요—감사와 고객 분쟁 해결에 필수적입니다.

보고 로직: 기간, 가용성, 예외 처리

데이터 모델 설계
무엇이든 코딩하기 전에 플래닝 모드로 엔티티, 규칙 및 예외 사례를 매핑하세요.

보고는 SLA 추적이 신뢰를 얻거나 의심받는 지점입니다. 앱은 어떤 기간을 측정했는지, 어떤 분이 계산 대상인지, 그리고 최종 수치가 어떻게 도출되었는지 분명히 해야 합니다.

기간: 캘린더, 청구 주기, 롤링 윈도우

고객이 실제로 사용하는 일반적인 보고 기간을 지원하세요:

  • 캘린더 월/분기(예: 3월 1–31일)
  • 청구 주기(예: 15일–다음달 14일, 인보이스에 맞춤)
  • 롤링 윈도우(예: “최근 30일”, 매일 업데이트)

기간을 month = 3 같은 방식으로 저장하지 말고 명시적 시작/종료 타임스탬프로 저장하여 나중에 계산을 재현할 수 있게 하세요.

가용성: 전체 분 vs 카운트되는 분

혼란의 흔한 원인은 분모가 전체 기간인지, 아니면 “카운트되는(eligible)” 시간인지입니다.

기간별로 두 값을 정의하세요:

  • Eligible minutes: SLA에 카운트되는 분(종종 예정 점검, 고객 원인 중단, 지원 시간 외 제외)
  • Downtime minutes: 서비스가 다운으로 간주된 eligible 분

그런 다음 계산:

availability_percent = 100 * (eligible_minutes - downtime_minutes) / eligible_minutes

eligible minutes가 0일 수 있는 경우(예: 해당 기간에 영업시간이 전혀 없음)에는 사전에 규칙을 정하세요: “N/A”로 표기하거나 100%로 처리하되 일관성 있고 문서화하세요.

수치 → 합격/불합격으로 전환

대부분의 SLA는 퍼센트와 이진 결과 둘 다 필요합니다.

  • 퍼센트: 예: 기간에 대한 99.95%
  • 합격/불합격: SLA 목표(예: ≥ 99.9%)와 비교

또한 대시보드가 임계값을 넘기기 전에 경고할 수 있도록 “위반까지 남은 거리”(남은 에러 버짓)를 유지하세요.

반드시 의도적으로 처리해야 할 예외들

  • 시간대: 고객/계약별 보고 시간대를 선택하고 이벤트를 일관되게 변환하세요(대개 고객 시간대 사용).
  • 서머타임(DST): 하루가 항상 1440분이라고 가정하지 마세요. 시간대 인식 타임스탬프를 사용해 기간 길이를 정확하게 계산하세요.
  • 종료 시간 누락: 인시던트에 해결 타임스탬프가 없을 수 있습니다. 이런 경우에는 “열려 있음”으로 처리하고 보고 종료 시간으로 캡핑하되 레코드를 정리하도록 플래그를 남기세요.

마지막으로 원시 입력(포함/제외된 이벤트 및 조정)을 보관해 모든 보고서가 “이 수치가 왜 그런가?”에 수동 설명 없이 답할 수 있게 하세요.

SLA 상태를 한눈에 알 수 있게 하는 UI와 대시보드

계산 엔진이 완벽해도 UI가 기본 질문인 “우리가 지금 SLA를 지키고 있는가, 그리고 이유는 무엇인가?”에 즉시 답하지 못하면 실패합니다. 각 화면이 명확한 상태로 시작하고 사람들이 수치와 그 수치를 만든 원시 이벤트로 드릴다운할 수 있게 설계하세요.

구축할 주요 뷰

개요 대시보드(운영자 및 매니저용). 현재 기간 준수, 가용성, 응답 시간 준수, 그리고 “위반 전 남은 시간” 같은 타일을 앞쪽에 배치하세요. 라벨은 명확하게(예: “이번 달 가용성”) 하세요. 다중 SLA를 지원하면 가장 나쁜 상태를 먼저 보여주고 확장할 수 있게 하세요.

고객 상세(어카운트 팀 및 고객용 보고). 고객 페이지는 해당 고객의 모든 서비스와 SLA 티어를 요약하여 간단한 합격/경고/실패 상태와 짧은 설명(예: “2개의 인시던트가 계산되었음; 18분 다운타임 반영됨”)을 보여야 합니다. /status(고객용 상태 페이지 제공 시)와 보고서 내보내기 링크를 추가하세요.

서비스 상세(심층 조사용). 이 페이지는 정확한 SLA 규칙, 계산 창, 준수 수치가 어떻게 형성되었는지의 분해를 보여줍니다. 시간에 따른 가용성 차트와 SLA에 포함된 인시던트 목록을 포함하세요.

인시던트 타임라인(감사용). 단일 인시던트 뷰는 이벤트 타임라인(감지, 확인, 완화, 해결)과 응답 및 해결 메트릭에 사용된 정확한 타임스탬프를 보여야 합니다.

실제 질문에 맞는 필터

화면 전반에 걸쳐 필터를 일관되게 하세요: 날짜 범위, 고객, 서비스, 티어, 심각도. 단위를 일관되게 사용하세요(분 vs 초; 소수 자리수). 사용자가 날짜 범위를 변경하면 페이지의 모든 지표를 업데이트해 불일치가 없게 하세요.

신뢰를 잃지 않는 드릴다운

각 요약 지표는 “왜?” 경로를 제공해야 합니다:

  • 준수 퍼센트 → 해당 기간에 계산된 인시던트 목록
  • 인시던트 → 계산에 사용된 원시 이벤트와 파생 타임스탬프
  • 가용성 → 다운타임 구간과 소스(모니터링 이벤트 vs 수동 조정)

툴팁은 최소한으로 사용해 “제외된 다운타임”이나 “영업시간” 같은 용어를 정의하고, 서비스 페이지에 정확한 규칙 문구를 표시해 사용자가 추측하지 않게 하세요.

단순하지만 분명하게

약어 대신 평이한 언어를 사용하세요(대상 사용자에게 친숙하다면 예외). 상태는 색상과 텍스트 레이블을 결합해 모호함을 피하세요(예: “위험: 에러 버짓의 92% 사용”). SLA 규칙과 제외를 변경한 경우 /settings/audit-log 같은 경로로 연결되는 작은 "마지막 변경" 박스를 추가해 사용자가 정의 변경 시점을 확인할 수 있게 하세요.

위반에 대한 알림 및 통지

두려움 없이 실험하세요
스냅샷과 롤백으로 안전하게 반복하면서 SLA 계산을 조정하세요.

알림은 SLA 추적 앱이 수동 보고에서 팀이 페널티를 피하도록 돕는 능동적 도구로 전환되는 지점입니다. 최고의 알림은 시기적절하고 구체적이며 실행 가능해야 합니다—단순히 “나쁨”을 알리는 것이 아니라 다음에 무엇을 해야 하는지 알려줘야 합니다.

실제 의사결정에 맞는 트리거 정의

세 가지 트리거 유형부터 시작하세요:

  • 접근 중인 위반: 예: “응답 시간 SLA를 맞추려면 30분 남음” 또는 “이번 달 가용성이 99.92%로 SLA(99.9%)에 근접” 등의 경고. 복구를 가능하게 하므로 가장 가치 있음.
  • 위반 발생: 계산 엔진이 해당 창에서 SLA 미충족을 확인할 때 발동.
  • 반복 위반: “30일 내 3회 위반” 또는 “같은 서비스가 이번 주에 2회 위반” 등 패턴 감지.

트리거는 고객/서비스/SLA별로 구성 가능하게 하세요. 서로 다른 계약은 서로 다른 허용치를 가집니다.

채널 선택과 메시지의 실행 가능성 유지

사람들이 실제로 대응하는 곳으로 알림을 보내세요:

  • 이메일: 감사용 및 외부 이해관계자 알림
  • Slack: 내부 빠른 협업
  • SMS(선택적): 고심각도 에스컬레이션

모든 알림에는 /alerts, /customers/{id}, /services/{id} 같은 딥 링크와 인시던트/이벤트 상세 페이지 링크를 포함해 응답자가 빠르게 숫자를 검증하도록 하세요.

노이즈 감소: 중복 제거, 조용한 시간, 에스컬레이션

같은 키(고객 + 서비스 + SLA + 기간)를 가진 알림을 그룹화하고 쿨다운 윈도우 동안 반복을 억제하는 중복 제거를 구현하세요.

팀 시간대별 조용한 시간을 추가해 비치명한 “접근 중인 위반” 알림이 영업시간까지 대기하도록 하고, 심각도가 높으면 “위반 발생”이 조용한 시간을 무시하도록 하세요.

마지막으로 에스컬레이션 규칙(예: 10분 후 온콜 알림, 30분 후 매니저에게 에스컬레이션)을 지원해 알림이 한 곳에만 머무르지 않게 하세요.

접근 제어, 인증, 감사 로그

SLA 데이터는 내부 성능과 고객별 권한을 노출할 수 있어 민감합니다. 접근 제어는 SLA “수학”의 일부로 다뤄야 합니다: 동일한 인시던트라도 어떤 고객의 SLA를 적용하느냐에 따라 결과가 달라질 수 있습니다.

초기부터 지원할 역할

역할은 단순하게 시작하고 필요하면 세분화하세요.

  • Admin: 전역 설정, 서비스·SLA·사용자·통합·청구 항목 관리
  • Agent: 인시던트/점검 창 생성·업데이트, 이벤트 첨부, 사후 분석 메모 추가
  • Manager: 범위 내 모든 읽기, SLA 정의 승인, 보고서 내보내기
  • Customer viewer: 자신의 서비스·SLA 목표·인시던트 이력·고객용 보고만 보기

실용적인 기본은 RBAC + 테넌트 스코핑입니다:

  • 모든 레코드(서비스, SLA 정책, 보고서)는 소유 테넌트/고객을 가짐
  • 내부 사용자는 여러 테넌트로 스코프 가능, 고객 뷰어는 정확히 하나로 제한
  • 편집 권한은 조회 권한보다 좁게(예: 에이전트는 인시던트를 편집할 수 있으나 SLA 규칙은 변경 불가)

각 역할의 보기/편집 권한

고객별 데이터에 대해 명확히 하세요:

  • 고객 뷰어는 내부 전용 필드(근본 원인 가설, 내부 심각도, 온콜 노트, 비공개 태그)를 절대 보지 못하게 하세요.
  • SLA 정책은 버전 관리하여 고객이 해당 인시던트 당시 적용되었던 SLA 조건을 볼 수 있게 하세요.

인증 옵션

초기에 이메일/비밀번호로 시작하고 내부 역할에는 MFA를 요구하세요. 나중에 **SSO(SAML/OIDC)**를 추가할 수 있도록 신원(identity)과 권한(authorization)을 분리해 설계하세요. 통합용으로는 좁은 범위의 서비스 계정 API 키를 발급하고 회전(rotation)을 지원하세요.

감사 로그(나중에 감사하게 될 항목)

다음에 대한 불변 감사 항목을 추가하세요:

  • SLA 규칙 변경(임계값, 캘린더, 제외, 서비스/고객 매핑)
  • 인시던트 편집(타임스탬프, 상태 전환, 수동 다운타임 오버라이드)
  • 권한 및 API 키 변경

누가, 무엇을 변경했는지(전/후), 언제, 어디서(IP/UA), 그리고 상관관계 ID를 저장하세요. 감사 로그는 검색 가능하고 내보낼 수 있게(/settings/audit-log).

통합 및 자동화를 위한 API 설계

SLA 트래킹 앱은 대개 고립되어 있지 않습니다. 모니터링 도구, 티켓 시스템, 내부 워크플로가 인시던트 생성, 이벤트 푸시, 보고서 조회를 자동화할 수 있는 API가 필요합니다.

작고 예측 가능한 API 표면부터 시작

버전이 명시된 기본 경로(예: /api/v1/...)를 사용해 페이로드를 진화시켜도 기존 통합이 깨지지 않도록 하세요.

대부분의 사용 사례를 커버하는 필수 엔드포인트:

  • Events: POST /api/v1/events(상태 변경 수집), GET /api/v1/events(감사·디버깅)
  • Incidents: POST /api/v1/incidents, PATCH /api/v1/incidents/{id}(확인, 해결, 할당), GET /api/v1/incidents
  • SLAs: GET /api/v1/slas, POST /api/v1/slas, PUT /api/v1/slas/{id}(계약·임계값 관리)
  • Reports: GET /api/v1/reports/sla?service_id=...&from=...&to=...(준수 요약)
  • Alerts: POST /api/v1/alerts/subscriptions(웹후크/이메일 대상 관리), GET /api/v1/alerts(알림 기록)

페이징과 필터링을 일관되게

하나의 관례를 정하고 모든 곳에서 사용하세요. 예: limit, cursor 기반 페이징, 표준 필터(service_id, sla_id, status, from, to). 정렬도 예측 가능하게(sort=-created_at).

통합자가 의존할 수 있는 에러 응답 정의

통합자가 처리할 수 있게 구조화된 에러를 반환하세요. 예:

{ "error": { "code": "VALIDATION_ERROR", "message": "service_id is required", "fields": { "service_id": "missing" } } }

명확한 HTTP 상태 사용(400 유효성, 401/403 인증/권한, 404 없음, 409 충돌, 429 속도 제한). 이벤트 수집에는 멱등성(Idempotency-Key)을 고려해 재시도가 인시던트를 중복 생성하지 않게 하세요.

속도 제한과 기본 보안

토큰별 합리적 속도 제한을 적용하고(수집 엔드포인트는 더 엄격), 입력을 정제하고 타임스탬프/타임존을 검증하세요. 범위가 좁은 API 토큰(읽기 전용 보고 vs 인시던트 쓰기 권한)을 권장하고 누가 어떤 엔드포인트를 호출했는지 로그에 남겨 추적 가능하게 하세요(감사 로그 섹션 참조, /blog/audit-logs).

테스트 전략: 수치가 정확함을 증명하라

이벤트 소스 연결
모니터링 및 티켓 시스템용 이벤트 수집 엔드포인트를 더 빠르게 구축하세요.

SLA 수치는 사람들이 신뢰할 때만 유용합니다. SLA 트래킹 앱의 테스트는 “페이지가 로드되는가”보다 “계산이 계약대로 정확히 작동하는가”에 집중해야 합니다. 계산 규칙을 별도의 제품 기능으로 취급해 자체 테스트 스위트를 만드세요.

고정 타임라인으로 규칙 단위 테스트

결정론적 입력(인시던트 오픈, 확인, 완화, 해결 타임라인)과 명확한 SLA 규칙 세트로 계산 엔진을 단위 테스트하세요.

고정 타임스탬프를 사용하고 시간을 고정(freeze)해 테스트가 시스템 시간에 의존하지 않게 하세요. 다음과 같은 엣지 케이스를 커버하세요:

  • 인시던트가 보고 기간 이전에 시작해 기간 내에 종료되는 경우
  • 중첩 인시던트(다운타임을 합병할지 쌓을지)
  • 여러 번의 일시중지(점검, 고객 대기 등)
  • 경계 분/초(정각, 월말, 윤일)

전체 파이프라인을 검증하는 E2E 테스트

이벤트 수집 → 계산 → 보고 생성 → UI 렌더링의 전체 플로우를 검증하는 소수의 고가치 E2E 테스트를 추가하세요. 이것들은 엔진이 계산한 값과 대시보드가 보여주는 값 사이의 불일치를 잡아냅니다. 시나리오는 적되 의미 있게 유지하고 최종 수치(가용성 %, 위반 여부, 응답 시간 등)를 단언하세요.

캘린더 및 시간대용 재사용 가능한 픽스처 구축

영업시간, 공휴일, 시간대에 대한 테스트 픽스처를 만드세요. 예: “인시던트가 현지 금요일 17:55에 발생” 또는 “공휴일로 인해 응답 시간 계산이 멈춤” 같은 반복 가능한 케이스.

SLA 앱 자체 모니터링

배포 이후에도 테스트는 계속됩니다. 작업 실패, 큐/백로그 크기, 재계산 소요 시간, 오류율에 대한 모니터링을 추가하세요. 수집 지연이나 야간 작업 실패 시 코드가 올바르더라도 보고서가 틀릴 수 있습니다.

배포, 운영, 실용적인 MVP 로드맵

SLA 트래킹 앱을 출시하는 것은 화려한 인프라보다 예측 가능한 운영에 관한 것입니다: 계산은 제때 실행되어야 하고, 데이터는 안전해야 하며, 보고서는 재현 가능해야 합니다.

단순하고 신뢰할 수 있는 배포 경로

초기에는 관리형 서비스를 사용해 정확성에 집중하세요:

  • 관리형 DB(PostgreSQL): 자동 백업, 시점 복구, 암호화
  • 컨테이너 호스팅(웹/API): 롤백 용이, 일관된 환경
  • 오브젝트 스토리지: CSV/PDF 내보내기와 대형 아티팩트, 라이프사이클 규칙

환경은 최소화하세요: dev → staging → prod, 각자 DB와 시크릿을 분리.

처음부터 필요한 백그라운드 작업

SLA 추적은 순수한 요청/응답이 아닙니다; 예약 작업에 의존합니다.

  • 계산 작업: 새 이벤트로 SLA 창 재계산, 지연 도착 데이터에 대한 재실행
  • 보고 생성: 일간/월간 요약 및 고객용 내보내기
  • 데이터 정리: 오래된 원시 이벤트 보관, 파생 테이블 압축, 참조 무결성 검증

작업은 워커 프로세스+큐나 관리형 스케줄러로 실행하세요. 작업은 멱등성을 보장하고 각 실행을 로깅해 감사 가능하게 만드세요.

보존 정책 및 내보내기

데이터 유형별 보존 기간을 정의하세요: 파생된 준수 결과는 원시 이벤트보다 오래 보관하세요. 내보내기는 우선 CSV(빠르고 투명)로 제공하고 나중에 PDF 템플릿을 추가하세요. 데이터베이스가 진실의 출처임을 명확히 하세요—내보내기는 표시용이며 형식은 베스트 에포트입니다.

범위 관리를 위한 단계적 로드맵

  1. MVP: 하나의 서비스, 하나의 SLA, 하나의 시간대, 기본 대시보드 + 월간 보고서
  2. 추가 지표: 응답시간 SLA, 점검 창, 제외 규칙, 다중 캘린더
  3. 고객 포털: 고객별 뷰, 접근 제어, 다운로드 가능한 보고서
  4. 상태 페이지: 계산된 가용성을 기반으로 한 공개/비공개 상태 페이지(참조: /blog/status-pages)

빠른 프로토타이핑을 위한 Koder.ai(선택 사항)

데이터 모델, 수집 흐름, 보고 UI를 빠르게 검증하려면 Koder.ai 같은 바이브 코딩 플랫폼을 고려할 수 있습니다. Koder.ai는 채팅을 통해 완전한 애플리케이션(웹 UI + 백엔드)을 생성하므로 다음을 빠르게 시제품으로 만들어 볼 수 있습니다:

  • 컴플라이언스, 에러 버짓, 드릴다운 타임라인을 위한 React 대시보드
  • 원시 이벤트 및 기간 결과를 저장하는 Go + PostgreSQL 백엔드
  • 내보내기/보고 엔드포인트와 간단한 고객 포털 뷰

요구사항과 계산이 입증되면(가장 어려운 부분), 소스 코드를 추출해 전통적인 빌드·운영 워크플로로 옮길 수 있습니다. 빠른 반복 중에도 스냅샷과 롤백 같은 기능을 유지하는 것이 좋습니다.

자주 묻는 질문

SLA 트래킹 웹 앱에서 “SLA 준수”는 무엇을 의미하나요?

SLA 트래커는 한 가지 질문에 증거를 가지고 답합니다: 특정 고객과 기간에 대해 계약상 약속을 지켰는가?

실무적으로는 모니터링, 티켓, 수동 업데이트 같은 원시 신호를 수집하고, 고객의 규칙(영업시간, 제외 항목 등)을 적용하여 감사 가능한 합격/불합격 결과와 상세 근거를 생성하는 것을 의미합니다.

SLI, SLO, SLA는 어떻게 다르고 왜 앱에서 따로 모델링해야 하나요?

아래와 같이 구분해 사용하세요:

  • SLI: 원시 측정치(예: 성공 체크 비율, 첫 응답 시간).
  • SLO: 내부 목표(대개 계약보다 더 엄격함).
  • SLA: 외부에 약속한 조건(대개 크레딧 또는 벌칙과 연결).

이들을 별도로 모델링하면 신뢰성 개선을 위한 내부 목표(SLO)를 바꾸더라도 계약상 보고(SLA)를 실수로 변경하지 않을 수 있습니다.

MVP로 어떤 SLA 지표부터 구현해야 하나요?

MVP로는 보통 1~3개의 핵심 지표를 엔드투엔드로 추적하는 것이 좋습니다:

  • 각 서비스별 월별 가용성(%)
  • 영업시간 기준의 첫 사람 응답 시간(TTFR)
  • 고심각도 사고에 대한 해결 시간(TTR)

이들은 실제 데이터 소스에 매핑하기 쉽고(기간, 달력, 제외 규칙 등) 까다로운 부분을 일찍 구현하게 합니다.

데이터베이스나 계산기 작성 전에 어떤 입력이 필요하나요?

요구사항 오류는 대개 명시되지 않은 규칙에서 옵니다. 설계 전에 다음을 수집하고 문서화하세요:

  • 계약/SLA 문서(부속서 포함)
  • 고객이 어떤 플랜에 속하는지(티어 매핑)
  • 고객/서비스별 시간대와 영업시간
  • 명시적 제외 항목(정기 점검, 고객 원인 지연, 불가항력, 유예 기간)

규칙이 명확히 표현되지 않으면 코드로 추론하지 말고 질문해서 명확히 하세요.

신뢰할 수 있는 SLA 트래커의 최소 데이터 모델은 무엇인가요?

신뢰할 수 있는 SLA 트래커의 최소 데이터 모델은 다음과 같은 명시적 엔터티로 시작하세요:

  • 고객(테넌트)
  • 서비스(측정 대상)
  • 플랜(상업적 래퍼)
  • SLA 정책(목표·측정 창·제외 규칙)
  • 인시던트(사람이 이해할 수 있는 그룹)
  • 이벤트(수학에 사용되는 불변 사실)

목표는 추적성입니다: 보고된 수치는 특정 event_id들과 특정 정책 버전으로 연결되어야 합니다.

타임스탬프와 시간대(DST 포함)는 어떻게 저장해야 하나요?

시간을 정확하고 일관되게 저장하세요:

  • occurred_atUTC(타임존 의미 포함)로 저장
  • received_at도 저장(앱이 이벤트를 수신한 시각)
  • 고객의 IANA 타임존 문자열은 표시와 영업시간 로직에 사용하되, 이벤트 시간을 재작성하지 마세요

그리고 기간은 명시적 시작/종료 타임스탬프로 저장해 DST 변경 시에도 보고를 재현할 수 있게 합니다.

중복이나 잘못된 데이터가 보고를 망치지 않게 이벤트를 신뢰성 있게 수집하려면?

모든 것을 단일 내부 event 형태로 정규화하고, 안정적인 고유 ID를 부여하세요:

  • event_id(재시도 시에도 안정적이어야 함)
  • source, event_type, occurred_at, service_id
  • 선택적 incident_id, attributes

event_id에 고유 제약을 걸어 중복 삽입을 방지하세요. 매핑되지 않거나 순서가 어긋나는 이벤트는 검역(quarantine)하거나 플래그를 세워 자동으로 수리하지 마세요.

영업시간, 일시중지, 제외 항목이 적용될 때 TTFR/TTR을 어떻게 정확히 계산하나요?

지속시간을 계산할 때는 두 타임스탬프를 무턱대고 빼지 말고, 타임라인에서 합산된 구간(intervals) 으로 계산하세요.

청구 대상 시간(‘chargeable’)에서 제거할 구간을 명확히 정의하세요:

  • 영업시간 외
  • 고객 대기 상태로 인한 일시중지
  • 정책에서 제외된 정기 점검

파생된 구간과 이유 코드를 영구 저장해서 무엇이 계산에 포함되었는지 설명할 수 있어야 합니다.

가용성은 어떻게 계산하나요(전체 분 vs 카운트되는 분)?

분모(eligible minutes)와 분자(downtime minutes)를 명확히 구분해 추적하세요:

  • Eligible minutes: SLA에 포함되는 분(예: 지원시간, 정기점검 제외 등)
  • Downtime minutes: 서비스가 다운으로 간주된 eligible 분

그런 다음 다음 공식을 적용하세요:

availability_percent = 100 * (eligible_minutes - downtime_minutes) / eligible_minutes

또한 eligible minutes가 0일 때의 처리를 미리 정하고 문서화하세요(예: N/A 처리).

대시보드와 알림은 어떤 내용을 포함해야 유용하고 시끄럽지 않나요?

UI가 한눈에 “지금 SLA를 충족 중인가, 그 이유는 무엇인가”를 답하도록 만드세요:

  • 현재 기간의 준수 여부와 남은 에러 버짓(위반까지 남은 시간) 표시
  • 요약 → 계산에 포함된 인시던트 목록 → 원시 이벤트/구간으로 이어지는 드릴다운 경로
  • 서비스 페이지에 정확한 SLA 규칙 텍스트를 노출하여 추측을 피하게 함

알림은 행동 지향적이어야 합니다: 접근 중인 위반, 위반 발생, 반복 위반 등과 관련 페이지(/customers/{id}, /services/{id} 등)로 연결하세요.

Related posts