9. 공식 앱 조사 — 세 신호를 직접 오가기
이 장에서 처음 나오는 말3개
조사 구간investigation window- 오류와 지연이 들어 있는 시간 범위. 공식 앱은 장애 구간이 고정되지 않으므로 최근 5~15분을 직접 좁힌다.
상관 관계correlation- 같은 요청의 메트릭·로그·트레이스를 시간이나
trace_id로 이어 보는 것. exemplar표본 링크- 메트릭 한 점에 매달린 대표
trace_id. 그래프에서 트레이스로 바로 건너가게 한다.
8장의 LGTM port-forward, Java example, traffic generator가 모두 실행 중이어야 한다.
공식 앱은 요청마다 임의 지연을 넣고 약 30%에서 simulating an error 예외를 던진다. 고정된 장애
시나리오가 아니라 계속 들어오는 요청 속에서 오류 요청 하나를 골라 따라가는 실습이다.
| 신호 | 먼저 물을 질문 | 이번 단서 |
|---|---|---|
| Prometheus | 요청과 지연이 실제로 들어오는가 | request rate · p95 · 500 비율 |
| Loki | 500일 때 무슨 문장이 남았나 | simulating an error |
| Tempo | 그 요청은 얼마나 걸렸고 어떤 상태인가 | GET /rolldice error span |
실습 1 — 메트릭으로 오류와 지연 찾기
섹션 제목: “실습 1 — 메트릭으로 오류와 지연 찾기”Grafana 오른쪽 위 시간 범위를 Last 5 minutes로 맞추고 Explore에서 Prometheus를 선택한다. traffic을 오래 켜 두었다면 Last 15 minutes부터 시작해도 된다.
-
요청이 들어오는지 확인한다
공식 Java example의 dashboard가 사용하는 metric으로 초당 요청량을 본다.
sum(rate(http_server_request_duration_seconds_count{service_name="rolldice"}[1m])) -
상태 코드별 요청량을 나눈다
sum by (http_response_status_code) (rate(http_server_request_duration_seconds_count{service_name="rolldice"}[1m]))200과500계열이 함께 보이면 공식 앱의 의도적 오류가 metric에도 반영된 것이다. -
p95 지연을 확인한다
histogram_quantile(0.95,sum by (le, http_route) (rate(http_server_request_duration_seconds_bucket{service_name="rolldice"}[1m])))공식 앱은 Gaussian 값을 바탕으로 sleep 시간을 만들므로 매 요청의 지연이 다르다. 짧은 구간의 p95가 일정하지 않은 것이 정상이다.
🔎 관찰 포인트: 약 30%는 코드의 분기 확률이지 1분 그래프가 항상 정확히 0.3이라는 뜻이 아니다. 요청 수가 적으면 비율이 크게 흔들리고, 이동창 때문에 traffic을 멈춘 뒤에도 잠시 값이 남는다.
실습 2 — 로그에서 오류 문장 찾기
섹션 제목: “실습 2 — 로그에서 오류 문장 찾기”Explore에서 Split을 눌러 오른쪽 pane을 만들고 Loki를 선택한다. 먼저 서비스 전체 로그를 연다.
{service_name="rolldice"}성공 로그와 framework 로그가 함께 보이면 문자열 필터를 붙인다.
{service_name="rolldice"} |= "simulating an error"오류 한 줄을 펼쳐 trace_id · span_id · severity_text가 있는지 확인한다. 매 요청마다 바뀌는
trace_id는 Loki stream label이 아니라 구조화 metadata다. 그래서 서비스 label로 stream을 좁힌 뒤
본문과 metadata를 읽는다.
실습 3 — 오류 로그에서 Tempo로 이동하기
섹션 제목: “실습 3 — 오류 로그에서 Tempo로 이동하기”-
오류 로그 상세의
trace_id옆 Trace 링크를 누른다. -
Tempo에서
GET /rolldiceserver span의 status가 error인지 확인한다. -
span attribute에서
http.response.status_code=500과http.route=/rolldice를 찾는다. -
Logs for this span을 눌러 같은
trace_id의 Loki 로그로 돌아온다.
Trace 링크가 없다면 Tempo Explore에서 직접 찾는다.
{ resource.service.name = "rolldice" && status = error }공식 example은 서비스 하나라서 inventory.reserve 같은 downstream child span은 없다. 이번 실습의
성공 조건은 분산 원인 분석이 아니라 500 metric → 오류 로그 → 같은 요청의 error trace → 같은 로그가
끊기지 않는지 확인하는 것이다.
실습 4 — metric exemplar로 바로 이동하기
섹션 제목: “실습 4 — metric exemplar로 바로 이동하기”Prometheus pane의 p95 query에서 Exemplars 표시를 켠다. 그래프 위 exemplar가 보이면 점을 눌러
trace_id와 Trace 링크를 확인한다. Grafana 공식 데이터소스 설정은 Prometheus의 trace_id를
Tempo로 보내도록 프로비저닝되어 있다.
exemplar가 없는 구간도 정상일 수 있다. 모든 측정값이 exemplar가 되는 것은 아니므로 traffic을 더 발생시키고 시간 범위를 넓혀 다시 본다. 로그 경로와 exemplar 경로 둘 중 하나만 확인하고 끝내지 않는다.
스스로 해볼 과제
섹션 제목: “스스로 해볼 과제”[1m]을[5m]으로 바꿔 상태 코드별 그래프와 p95가 얼마나 부드러워지는지 비교한다.{service_name="rolldice"}와 오류 문자열을 붙인 query의 결과 수 차이를 확인한다.- TraceQL에서
status = error를 빼고 duration 조건을 추가해 가장 느린 성공 요청도 찾아본다. - traffic을 멈춘 뒤 request rate가 즉시 0이 되지 않는 이유를 이동창으로 설명한다.
안 보일 때 어디를 보나
섹션 제목: “안 보일 때 어디를 보나”| 증상 | 확인 |
|---|---|
| 모든 query가 비어 있음 | terminal A의 port-forward와 terminal B·C 프로세스가 모두 살아 있는지 확인 |
| metric만 없음 | Java example 터미널의 OTLP exporter 오류와 4317·4318 전달 확인 |
http_response_status_code가 없음 | metric label browser에서 실제 status label을 확인 — agent semantic convention 차이 |
| 오류 로그가 없음 | {service_name="rolldice"}로 넓히고 ERROR와 exception stack trace 확인 |
| 로그에 Trace 링크 없음 | 로그 상세에 trace_id metadata가 있는지 먼저 확인 |
| error trace가 없음 | traffic을 더 발생시키고 Tempo 시간 범위를 Last 15 minutes로 확대 |
| exemplar가 없음 | Prometheus query의 Exemplars 표시와 시간 범위를 확인 |
다음 장에서 환경 재사용하기
섹션 제목: “다음 장에서 환경 재사용하기”세 터미널과 kind 클러스터를 유지한다. 다음 장은 방금 검증한 query를 Grafana dashboard로 옮긴다.
여기서 끝낸다면 각 터미널에서 Ctrl+C를 누르고 전용 클러스터만 지운다.
kind delete cluster --name observability-lab참고 자료
섹션 제목: “참고 자료”- 공식 Java
RollController— 임의 지연과 오류 분기 원문 - 공식 Java dashboard JSON — request rate와 latency metric 이름의 공식 사용 예
- 공식 Grafana 데이터소스 설정 — exemplar, derived field, trace to logs 프로비저닝
- Grafana Logs in Explore — 로그 상세와 data link 사용법