Prometheus·Grafana로 시스템을 관찰한다는 것 — 메트릭 설계부터 알람까지
Prometheus의 Pull 모델과 메트릭 타입, PromQL 쿼리, Grafana 알람 설정, CPU/메모리/I/O 핵심 지표와 카디널리티 관리까지 실전 모니터링 체계를 정리한다
2026-08-12 · 최초 발행 2026-01-16
시스템이 죽고 나서 로그를 뒤지는 방식으로는 이미 늦다. 모니터링의 목적은 문제가 커지기 전에 신호를 잡아내는 것이고, 그 신호를 어떻게 수집·저장·시각화·통보할지가 Prometheus와 Grafana 스택이 하는 일이다.
관찰성은 여러 관점으로 본다
시스템 상태를 파악하는 데는 세 가지 축이 있다. Metrics는 CPU 사용률·메모리·요청 처리 시간처럼 시간에 따른 수치 데이터로 집계와 추세 분석에 맞고, Logs는 구조화(JSON)든 비구조화든 이벤트 기록이자 디버깅 정보로 ELK Stack(Elasticsearch, Logstash, Kibana)이 대표적인 처리 도구다. Traces는 분산 시스템에서 요청이 어떤 경로를 거쳤는지 추적해 마이크로서비스 간 의존성을 드러내며 Jaeger, Zipkin 같은 도구로 다룬다.
관측 방식도 관점에 따라 나뉜다. Blackbox Monitoring은 HTTP 엔드포인트 응답 시간·가용성처럼 외부에서 본 동작을 확인해 사용자 경험 중심으로 접근하고, Whitebox Monitoring은 애플리케이션 로직이나 DB 쿼리 성능 같은 내부 메트릭을 수집해 근본 원인 분석까지 들어간다.
Prometheus는 어떻게 데이터를 모으는가
Prometheus Server는 메트릭을 스크래핑해 내장 시계열 데이터베이스(TSDB)에 저장하고 PromQL로 조회하는 구조다. 특징은 Push가 아니라 Pull 모델이라는 점 — 타겟에서 주기적으로 메트릭을 긁어온다. Exporter는 각 시스템의 메트릭을 Prometheus가 읽을 수 있는 형식으로 바꿔주는데, Linux/Unix 시스템 메트릭을 담당하는 Node Exporter, MySQL·Redis처럼 애플리케이션별 Exporter, 비즈니스 메트릭을 위한 Custom Exporter가 있다. 배치 작업처럼 실행 시간이 짧아 Pull 방식으로 긁어오기 어려운 경우엔 Pushgateway가 Push 모델을 지원해서 Job이 끝난 뒤 메트릭을 밀어넣는다. 알람 규칙을 평가하고 전송하는 건 Alertmanager 몫으로, 그룹화·억제·침묵 기능과 Email·Slack·PagerDuty 같은 다양한 알림 채널을 지원한다.
메트릭은 네 가지 타입으로 나뉜다. Counter는 HTTP 요청 수나 에러 발생 횟수처럼 단조 증가만 하는 누적 값으로 rate() 함수로 초당 증가율을 계산한다. Gauge는 CPU 사용률·메모리 사용량·동시 접속자 수처럼 오르내리는 현재 값이다. Histogram은 요청 처리 시간 분포처럼 값을 버킷으로 집계해 백분위수 계산이 가능하고, Summary는 클라이언트 측에서 백분위수를 직접 계산해 정확도는 높지만 집계는 불가능하다.
PromQL로는 이런 식의 쿼리를 쓴다.
# CPU 사용률 (5분 평균)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 메모리 사용률
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
# HTTP 요청 에러율
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100
# 95 백분위수 응답 시간
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
Grafana로 보고, 알린다
대시보드는 여러 Panel 유형으로 구성한다. 시계열은 Graph, 단일 수치는 Stat, 게이지 차트는 Gauge, 분포는 Heatmap, 표 형식은 Table을 쓴다. Variable을 쓰면 인스턴스·환경·시간 범위를 선택하는 동적 대시보드를 만들 수 있고(Query Variable, Custom Variable), Templating으로 대시보드를 재사용하며 Multi-Tenancy도 지원한다.
알람 규칙은 이런 형태다.
groups:
- name: system_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is above 80% (current value: {{ $value }})"
라우팅은 심각도별로 채널을 나누는 게 기본이다(critical → PagerDuty, warning → Slack). 여기에 업무시간 외에는 일부 알람을 억제하는 시간대별 정책, 미응답 시 상위 담당자에게 넘기는 에스컬레이션 정책을 더한다.
CPU·메모리·I/O, 어디를 봐야 하는가
CPU는 user(사용자 공간)·system(커널 모드)·iowait(I/O 대기)·idle(유휴) 네 상태로 나눠 본다. Load Average는 1분·5분·15분 평균 부하를 CPU 코어 수와 비교해 포화 상태를 판단하는데, 대략 코어 수의 0.7배를 넘어가면 주의가 필요하다. Context Switch는 프로세스·스레드 전환 빈도로, 과도하면 성능 저하 원인이 되며 vmstat으로 측정한다.
메모리는 Total(전체)·Used(사용 중)·Free(완전히 비어 있음)·Available(Free + Cache/Buffer, 즉시 할당 가능) 네 값을 구분해야 한다. Swap In/Out이 발생하면 성능이 급격히 떨어지고 SwapUsed가 0보다 큰 상태가 지속되면 메모리 부족 신호다 — vm.swappiness 파라미터(기본값 60)를 10 이하로 낮추는 걸 권장한다. 메모리가 부족하면 커널이 프로세스를 강제 종료하는 OOM Killer가 개입하는데, 어떤 프로세스를 죽일지는 oom_score로 결정되고 로그에서 "Out of memory: Kill process" 문구로 확인할 수 있다.
I/O는 초당 작업 수(IOPS), 초당 읽기/쓰기 바이트(Throughput), 요청 처리 시간(Latency)을 iostat·iotop으로 측정한다. iowait(CPU가 I/O 완료를 기다리는 비율)가 10%를 넘게 지속되면 디스크 병목을 의심하고 SSD 전환이나 RAID 구성을 검토해야 한다. 네트워크 I/O는 수신·송신 패킷 수와 바이트, 에러·드롭 패킷 비율, 대역폭 사용률을 netstat·iftop으로 확인한다.
시스템 메트릭 너머, 비즈니스 메트릭
인프라 지표만으로는 부족하다. 주문 처리율, 결제 성공률, 사용자 가입 수, 활성 사용자, API 응답 시간 분포 같은 비즈니스 메트릭도 함께 봐야 한다. 이걸 구조화하는 두 가지 프레임이 있다. 요청 기반으로 보는 RED 메서드는 초당 요청 수(Rate), 에러율(Errors), 응답 시간(Duration)을 본다. 리소스 기반으로 보는 USE 메서드는 사용률(Utilization), 대기 큐 길이(Saturation), 에러 발생 수(Errors)를 본다.
메트릭과 알람을 설계할 때 지켜야 할 것들
메트릭 설계에서 가장 자주 터지는 문제는 카디널리티다. 레이블 조합 수는 보통 수천수만 개 수준으로 관리해야 하고, 사용자 ID나 이메일처럼 값이 무한히 늘어나는 고유값을 레이블로 쓰면 안 된다 — 집계 가능한 차원만 레이블로 잡아야 한다. 스크래핑 간격은 기본 15초1분 사이에서 네트워크 부하와 정확도의 균형을 맞추고, 중요한 메트릭은 짧게, 참고용은 길게 가져간다.
알람은 실행 가능한 것만 설정해야 피로도가 안 쌓인다. for 절로 일시적인 스파이크를 무시하고 임계값은 지속적으로 조정한다. SLO/SLA 기반으로 Error Budget 소진율을 모니터링하는 방식도 있는데, 예를 들어 99.9% 가용성 목표라면 월간 43분의 다운타임까지는 허용되는 셈이고, 이 예산이 얼마나 빠르게 소진되는지를 보는 Burn Rate 알람으로 조기에 감지할 수 있다.
보안 측면에서는 Grafana RBAC, Prometheus API 인증, 네트워크 방화벽으로 접근을 통제해야 한다. 데이터 보존은 Prometheus 기본값이 15일이고, 더 길게 가져가려면 Thanos·Cortex·VictoriaMetrics 같은 장기 보관 솔루션에 다운샘플링을 적용해 저장 공간을 아낀다.
결국 모니터링은 CPU·메모리·I/O 같은 시스템 지표와 비즈니스 지표를 함께 추적해 문제를 조기에 잡아내고 용량 계획을 세우는 일이다. 메트릭을 비즈니스 요구에 맞게 설계하고, 알람 임계값을 계속 다듬고, 대시보드를 손봐 나가는 게 안정적인 운영의 출발점이다.