
Prometheus는 SoundCloud에서 만든 시스템 및 서비스의 상태를 모니터링하는 오픈소스 모니터링 시스템이다.
현재는 Kubernetes 다음으로 인기있는 CNCF 프로젝트라고 볼 수 있다.
Prometheus는 특히 메트릭 수집과 알람에 특화되어있다.
메트릭 수집의 경우 HTTP 엔드 포인트를 통한 pull 방식으로 이루어지고 있다.
/metrics 엔드포인트 호출| Pull (Prometheus) | Push (기존 방식) |
|---|---|
| 앱이 모니터링 서버 주소 몰라도 됨 | 앱이 모니터링 서버 주소 알아야 함 |
| 네트워크 문제 시 바로 감지 | 데이터가 안 오면 이유를 모름 |
| 수집 주기를 중앙에서 관리 | 각 앱마다 따로 설정 |
| 방화벽 설정이 복잡할 수 있음 | 방화벽 설정 간단 |
시계열 데이터란 모든 데이터를 시간과 함께 저장하는 것이다.
시간별로 데이터가 어떻게 변했는지 기록하는 것처럼 시간별로 데이터가 저장된다.
"시간" + "벨류"
대신 과거 데이터를 수정하지 않고 계속 쌓기만 한다. 따라서 시간 기반 계산에 최적화되어있다.
웹브라우저로 http://.../metrics 접속하면 보이는 내용
http_requests_total{method="GET", endpoint="/login"} 1234
http_requests_total{method="POST", endpoint="/signup"} 567
memory_usage_bytes 1073741824
cpu_usage_percent 45.2
http_requests_total, error_count_totalcpu_usage_percent, memory_usage_byteshttp_request_duration_secondsresponse_time_percentile라벨을 통해서 더 세밀하게 구분할 수 있다. key-value로 이루어져 있으며, 영문자로 시작해야한다.
여기서 __로 시작하는 이름은 prometheus에서 내부적으로 사용하는 예약어라 사용하면 안된다.
http_requests_total{
method="POST", # 값이 제한적 (GET, POST, PUT, DELETE)
endpoint="/api/users", # 엔드포인트 수는 한정적
status="200", # HTTP 상태 코드 (200, 404, 500 등)
env="production" # 환경 (dev, staging, production)
}
http_requests_total{
user_id="user_123456", # 수백만 개의 고유값 -> 메모리 폭발
timestamp="2024-01-01" # 시간은 이미 자동 저장됨
}
주의사항: 라벨이 변경되면 변경된 라벨에 맞춰 새로운 시계열이 생성된다.
라벨 값이 바뀌면 다른 시계열로 취급되어 문제를 발생시킬 수 있다.
이렇게되면 시계열 데이터 수가 매우 증가할 수 있기 때문에 메모리 성능에 문제가 생길 수 있어 정말 필요한 부분에만 라벨을 처리하는게 중요하다.
Prometheus는 데이터를 저장하기 위해서 Chunk(청크)와 WAL(Write-Ahead-Log)를 사용한다.
청크는 여러개의 샘플을 하나의 덩어리로 묶은 데이터 구조이다.
만약 1시간 동안의 CPU 사용률 데이터의 경우 아래와 같다.
[10:00:00, 45%] [10:00:15, 47%] [10:00:30, 52%] ...
하나의 청크로 압축되어 디스크에 저장된다.
이렇게 압축된 청크 덕분에 Prometheus는 많은 데이터를 효율적으로 저장하고 빠르게 조회할 수 있다.
WAL은 데이터 안정성을 보장하는 로그 파일이다. 샘플이 수집되게되면 가장 먼저 WAL에 저장된다.
수집 → WAL에 즉시 기록 → 메모리 저장 → 청크로 압축 → 디스크 저장
WAL의 경우 만약 장애가 발생하게 되면 복구를 도와주는 중요한 역할을 하게 된다.
만약, Prometheus가 비정상적으로 종료되었을 경우에, WAL 파일을 읽어서 데이터를 복구할 수 있게 된다.
만약 문제가 있어 Prometheus가 재시작이 된다면 다음과 같은 과정을 거치게 된다.
# prometheus.yml
storage:
tsdb:
path: /var/lib/prometheus # 데이터 저장 경로
retention.time: 15d # 15일간 보관
retention.size: 10GB # 최대 10GB까지 저장
Prometheus는 자체 쿼리인 PromQL을 제공하며, 다양한 방식으로 메트릭을 집계하고 필터링한다.
# 5분간 초당 요청 수 (QPS)
rate(http_requests_total[5m])
# 엔드포인트별 에러율
sum(rate(http_requests_total{status=~"5.."}[5m])) by (endpoint)
/
sum(rate(http_requests_total[5m])) by (endpoint) * 100
# 메모리 사용률 80% 넘는 서버 찾기
(memory_usage_bytes / memory_total_bytes) > 0.8
# 특정 팀의 프로덕션 서버만 모니터링
cpu_usage{team="backend", env="production"}
Prometheus는 알람 기능도 제공하고 있기 때문에 임계값을 초과하면 알림을 발송해서 문제를 알고 대응할 수 있다.
groups:
- name: example
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 5m
annotations:
summary: "{{ $labels.endpoint }} 에러율 5% 초과"
description: "현재 에러율: {{ $value | humanizePercentage }}"
- alert: HighMemoryUsage
expr: memory_usage_bytes / memory_total_bytes > 0.9
for: 10m
annotations:
summary: "메모리 사용률 90% 초과"
PromQL의 쿼리 결과들은 보통 다른 모니터링 도구로 그래프와 대시보드 형태로 표현해 확인할 수 있다.
나의 경우 Grafana를 통해서 초기 대시보드 화면을 구현한적 있다.
직접 만든 화면은 회사 데이터가 있으므로 Grafana에서 가져온 것으로 대체한다.

Prometheus는 데이터 수집과 저장에 특화되어있고, 시각화는 주로 Grafana를 연동해서 사용하는 추세이다.
실제 Grafana Dashboard Template이 있어서 원하는 템플릿을 직접 가져와서 사용해도 된다.
나의 경우 데이터가 보이지 않거나 다른 데이터를 보여줘야할때 Panel을 추가해서 직접 PromQL로 데이터를 보여줬다
* Grafana Dashboard Template: https://grafana.com/grafana/dashboards/
Prometheus의 경우 분명 메트릭을 수집하는데 특화되어있다.
그러나 실제 운영에 있어서 모니터링앱을 구성할때는 메트릭 데이터만으로는 모니터링 앱을 만드는데 한계가 있다.
로그나 트레이싱을 지원하지 않기 때문에 완벽한 모니터링 앱을 만들고자한다면,
로그나 트레이싱(예., Jaeger) 데이터를 수집하는 다른 것들이 필요하다.