이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • 로그, 메트릭, 트레이스는 장애 원인 격리에서 각각 어떤 역할을 하는가?
  • 같은 시간대와 같은 요청으로 증거를 묶는 이유는 무엇인가?
  • 신호가 서로 충돌할 때 어떤 순서로 확인해야 하는가?

목적

이 Runbook은 장애 중 로그, 메트릭, 트레이스를 사용해 원인 후보를 좁히는 절차다.

로그는 사건을 설명한다.

메트릭은 규모와 추세를 설명한다.

트레이스는 요청이 지나간 경로와 병목을 설명한다.

세 신호를 따로 보면 각자 맞는 말처럼 보이지만 결론이 어긋날 수 있다.

같은 시간대, 같은 endpoint, 같은 요청 ID 기준으로 묶어야 실제 원인 격리가 된다.

적용 조건

  • 장애 원인 후보가 여러 개다.
  • 로그에는 오류가 적은데 사용자 영향이 크다.
  • p95가 상승했지만 어떤 endpoint가 느린지 불명확하다.
  • 특정 요청만 실패하는지 전체가 느린지 모른다.
  • 외부 의존성 문제인지 내부 코드 문제인지 구분해야 한다.
  • 장애 후 보고서에 근거를 남겨야 한다.

첫 5분

  1. 기준 시간 창을 정한다.
  2. 영향 endpoint와 status code를 하나 이상 고른다.
  3. 대표 요청 ID 또는 사용자/주문 샘플을 확보한다.
  4. 같은 시간대의 오류율, 응답 시간, 요청량을 본다.
  5. 같은 시간대의 로그 샘플을 본다.
  6. 가능하면 대표 요청의 trace를 찾는다.
  7. 가설과 배제한 원인을 타임라인에 남긴다.

시간대가 맞지 않으면 신호를 잘못 연결할 수 있다.

로그 확인

로그에서 확인할 것:

  • exception class와 메시지
  • endpoint, method, status
  • elapsed time
  • 요청 ID 또는 correlation id
  • 사용자군이나 주문 ID 같은 샘플 식별자
  • 외부 API 호출 결과
  • DB query timeout 또는 transaction rollback

주의할 점:

  • 개인정보와 민감 payload를 그대로 공유하지 않는다.
  • 로그가 많은 endpoint와 장애 endpoint를 구분한다.
  • error 로그가 없다고 장애가 없다고 판단하지 않는다.
  • sampling이나 log level 변경 여부를 확인한다.

로그는 “무슨 일이 일어났는가”를 보여 주지만 전체 규모는 metric으로 확인해야 한다.

메트릭 확인

메트릭에서 확인할 것:

  • 요청량
  • endpoint별 error rate
  • p50, p95, p99 응답 시간
  • DB connection pool active/waiting
  • JVM heap, GC pause, thread 수
  • queue depth와 consumer 처리량
  • 외부 API client error/latency

예시 PromQL:

sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) by (uri)
histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, uri))
max(hikaricp_connections_active) by (pool)

메트릭 label에 사용자 ID처럼 cardinality가 큰 값을 넣으면 운영 자체가 불안정해질 수 있다.

트레이스 확인

트레이스는 요청 경로를 보여 준다.

확인할 것:

  • controller, service, repository, external client 중 어디서 시간이 쓰였는가?
  • DB query span이 길어졌는가?
  • 외부 API span이 실패했는가?
  • retry 때문에 같은 호출이 반복되었는가?
  • trace sampling이 장애 요청을 충분히 잡고 있는가?

트레이스가 없더라도 요청 ID를 로그에 남기면 일부 경로를 복원할 수 있다.

장애 중에는 전체 trace 완성보다 원인 후보를 줄이는 데 필요한 span을 우선 본다.

신호가 충돌할 때

다음 순서로 확인한다.

  • 사용자 신고와 핵심 이벤트 수를 먼저 본다.
  • endpoint별 metric으로 규모를 확인한다.
  • 대표 요청 로그로 구체 사례를 본다.
  • trace로 병목 경로를 확인한다.
  • 최근 배포/설정/배치와 시간대를 맞춘다.
  • 의존성 metric과 애플리케이션 metric을 비교한다.

예를 들어 전체 CPU는 낮은데 p95가 높다면 DB 대기, 외부 API timeout, 특정 endpoint 편중을 본다.

로그에는 오류가 없는데 요청량이 급감했다면 Ingress, Load Balancer, client error, 인증 실패를 본다.

안전한 완화 조치

  • 원인 후보가 외부 API라면 timeout과 retry를 줄이고 fallback을 검토한다.
  • DB pool 대기가 원인이면 느린 query와 connection 사용량을 확인한 뒤 트래픽을 제한한다.
  • 특정 endpoint만 문제라면 기능 flag나 rate limit을 적용한다.
  • 로그 누락이 문제라면 장애 중 log level을 과도하게 올리기보다 샘플링과 대표 요청을 확보한다.
  • metric label 폭증이 의심되면 새 label 추가를 중단한다.

완화 후에는 같은 metric과 로그 기준으로 효과를 비교한다.

하지 말아야 할 대응

  • 서로 다른 시간대의 로그와 그래프를 연결하지 않는다.
  • 대표 요청 없이 전체 평균만 보고 원인을 단정하지 않는다.
  • 로그가 없다고 network 문제로 단정하지 않는다.
  • trace 하나만 보고 전체 장애 원인으로 일반화하지 않는다.
  • 장애 중 민감 payload를 공유 채널에 붙여 넣지 않는다.

인프라 담당자와 공유할 자료

  • 기준 시간 창과 timezone
  • 영향 endpoint와 status code
  • 대표 요청 ID 또는 샘플 식별자
  • 오류율, 응답 시간, 요청량 그래프 이름
  • 관련 로그 샘플의 비민감 요약
  • trace span에서 느린 구간
  • 최근 배포, 설정, 배치 시각

공유 자료는 재현 가능한 쿼리나 필터 이름으로 남기는 것이 좋다.

종료 조건

  • 장애 영향과 관련된 대표 신호가 정해졌다.
  • 최소 하나 이상의 원인 후보가 근거로 좁혀졌다.
  • 배제한 후보와 근거가 타임라인에 남았다.
  • 완화 조치 전후 비교 지표가 정해졌다.
  • 후속 보고서에 사용할 로그/메트릭/트레이스 링크가 남았다.

확인 질문

확인 질문

  • 로그, 메트릭, 트레이스의 역할은 어떻게 다른가?
    • 로그는 사건, 메트릭은 규모와 추세, 트레이스는 요청 경로를 설명한다.
  • 같은 시간대로 증거를 묶어야 하는 이유는 무엇인가?
    • 서로 다른 시간대의 신호를 연결하면 원인 후보를 잘못 좁힐 수 있기 때문이다.
  • 신호가 충돌하면 무엇을 먼저 봐야 하는가?
    • 사용자 영향과 핵심 이벤트 수를 먼저 보고, endpoint별 metric과 대표 요청 로그로 좁힌다.

리뷰 체크포인트

  • 기준 시간 창과 대표 요청을 먼저 정하는가?
  • 로그/메트릭/트레이스 역할이 분리되어 있는가?
  • PromQL 또는 필터 기준이 재현 가능한가?
  • 민감 정보 공유 금지가 포함되어 있는가?
  • 완화 전후 비교 지표가 정해져 있는가?