Introduce
PLG Stack(Promtail, Loki, Grafana)으로 효과적인 로그 모니터링 시스템 구축하기
Introduce📌 개요2025.01.25 - [DevOps/Monitoring] - 로그 시스템이 필요한가요? (ELK Stack과 PLG Stack) 로그 시스템이 필요한가요? (ELK Stack과 PLG Stack)개요 로그는 어떻게 수집해야할까? 나는 최근까지 로그
woojjam.tistory.com
이전 게시글에서는 PLG Stack으로 로그 모니터링 시스템을 구축해보았다. 이번 시간에는 SpringBoot Actuator, Prometheus, Grafana 를 활용하여 스프링 애플리케이션 모니터링 시스템을 구축해보고자 한다.
작전에 실패한 군인은 용서할 수 있지만 경계에 실패한 군인은 용서할 수 없다.
현역으로 복무중일때 정신 교육 시간때 자주 듣던 말이다. 철저한 경계를 통해 적의 기습을 방어하자라는 의미가 담기지 않았나 싶다.
모니터링은 애플리케이션의 성능과 안전성을 유지하기 위해서는 반드시 필수적인 요소이다. 경계와 똑같이 서버의 상태를 실시간으로 파악하고, 성능 이슈를 조기에 감지하여 빠르게 대응할 수 있도록 해준다. 이러한 모니터링을 통해 안정적인 서비스를 운영할 수 있게 된다고 생각한다.
Prometheus
프로메테우스는 메트릭 기반의 오픈소스 모니터링 시스템이다.
📌 메트릭
메트릭이란 시간에 따라 변화하는 수치 데이터이다.
CPU 사용률, 메모리 사용량, HTTP 요청 수 및 응답 시간 등이 모두 해당한다. 즉, 메트릭 기반이란 숫자 데이터를 중심으로 시스템의 상태와 성능을 모니터링 하고, Time Series Data로 시간에 따른 변화로 저장, 분석, 시각화하도록 설계되었다는 것이다.
따라서 이런 방식은 조회나 집계가 훨씬 효율적이라는 장점이 있다.
📌 특징
프로메테우스의 가장 큰 특징을 알아보면
- 메트릭 기반 모니터링
- 수치 데이터를 주기적으로 수집
- 수집 데이터를 Time Series 형태로 저장하여, 시간에 따른 변화 및 추세 분석 가능
- Pull 모델
- 모니터링 대상 서버로부터 PUSH 받는것이 아닌 설정한 주기(30초, 1분 등)에 따라 PULL 방식으로 메트릭 수집
- 특정 엔드포인트를 통해 메트릭을 노출하면, 프로메테우스가 이를 주기적으로 요청하는 형태
- PromQL
- 프로메테우스 쿼리 언어로 메트릭 데이터를 집계, 필터링, 연산 등을 명령어를 통해 수행 가능 (PromQL을 학습해야하므로 러닝커브가 존재)
- Label을 이용하여 메트릭 데이터 분류 가능
Spring Actuator
스프링 부트 애플리케이션의 다양한 운영 정보를 제공해주는 툴로 상태를 모니터링하고, 유용한 메트릭들을 제공한다. Actuator의 가장 큰 특징으로는 엔드포인트마다 제공되는 정보가 다르다는 것이다.
📌 엔드포인트
제공하는 엔드포인트들에 대해서는 해당 문서를 참고할 수 있다.
Endpoints :: Spring Boot
If you add a @Bean annotated with @Endpoint, any methods annotated with @ReadOperation, @WriteOperation, or @DeleteOperation are automatically exposed over JMX and, in a web application, over HTTP as well. Endpoints can be exposed over HTTP by using Jersey
docs.spring.io
다양한 엔드포인트를 제공하지만 그 중에서 몇가지만 알아보면
- health
- 애플리케이션의 전체적인 상태를 확인하기 위한 엔드포인트
- Blue/Green 무중단 배포를 구축하면서 /actuator/health 를 통해 헬스체크를 진행함으로 필요함
- promethues
- 애플리케이션의 메트릭을 수집하기 위해 노출된 엔드포인트
- 프로메테우스가 /actuator/promethues 를 주기적으로 호출하여 메트릭을 수집하므로 필요함
- loggers
- 애플리케이션에 설정된 각 로거의 이름과 로거 레벨을 확인할 수 있는 엔드포인트
- 특정 로거의 레벨을 런타임에 동적으로 변경 가능함으로 운영 환경의 로그 모니터링에 유용하기에 필요함
Architecture
모니터링 시스템을 구축하기 위해 사용할 Promethues 와 Actuator에 대해서는 간략하게 설명하였다. 본격적으로 시스템을 구축하기에 앞서 구축할 아키텍처를 그려보자.
이전 게시글에서 구축한 PLG Stack과 Promethus를 합친 예상 아키텍처이다.
- Spring Boot Actuator로 /actuator/prometheus 에 메트릭을 노출
- Prometheus가 설정된 스크랩(Scrape) 대상에 해당 엔드포인트를 추가해 일정 주기로 메트릭 수집
- 수집된 메트릭을 Prometheus가 Time Series DB에 저장
- Grafana에서 Prometheus를 데이터 소스로 등록, PromQL로 쿼리하여 다양한 시각화 대시보드 구성
전체적인 아키텍처의 흐르믄 이러한 순서가 될 것이다.
Implementation
Overview | Prometheus
An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.
prometheus.io
자세한 내용들은 해당 Docs를 참고하는 것을 추천합니다.
📌 Promethus 설치
먼저 Monitoring Server에 Prometheus를 구축해주어야한다. 일단 나는 PLG Stack 을 Docker Compose를 통해 설치하였으므로 Promethues도 똑같이 Docker Compose로 설치해줄것이다.
- docker-compose.yml
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--storage.tsdb.retention.time=3d'
- '--config.file=/etc/prometheus/prometheus.yml'
networks:
- loki
--storage.tsdb.retention.time=3d 은 수집한 메트릭을 3일(3d) 동안 보관하고, 이후엔 자동으로 오래된 데이터를 삭제 하기 위해 설정해주었다.
해당 설정을 적용한 이유는 아무런 설정을 적용하지 않을 경우 기본적으로 프로메테우스는 15일동안 수집한 메트릭을 보관한다. 하지만 현재 구축한 모니터링 서버는 EC2 t3.micro 를 사용중이라 가용할 수 있는 메모리 공간과 디스크 공간이 매우 제한적이다. 그러므로 보관 기간을 길게 설정하면 그만큼 디스크 사용량이 증가하므로 이러한 상황을 고려하여 최대한 리소스를 절약하기 위해서 3일로 설정해주었다.
Storage와 관련된 설정은 해당 파트를 참고하면 자세히 알 수 있다.
Storage | Prometheus
An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.
prometheus.io
📌 prometheus 설정
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: ['prometheus:9090']
- job_name: 'grafana'
scrape_interval: 5s
static_configs:
- targets: ['grafana:3000']
- job_name: 'prod_app_server' # {PORT}에 대한 App Name
metrics_path: '/actuator/prometheus'
scrape_interval: 15s
static_configs:
- targets:
- '{SERVER_ADDRESS}:{PORT}'
labels:
app_name: 'prod_app_server'
- job_name: 'prod_owner_server' # {PORT}에 대한 App Name
metrics_path: '/actuator/prometheus'
scrape_interval: 15s
static_configs:
- targets:
- '{SERVER_ADDRESS}:{PORT}'
labels:
app_name: 'prod_owner_server'
Prometheus의 설정 파일이다.
1. Global
global:
scrape_interval: 15s
evaluation_interval: 15s
전역적으로 프로메테우스가 메트릭을 수집하는 주기와 정의된 룰을 평가하는 주기를 설정하며 15초로 지정하였다.
2. scrape_configs
프로메테우스가 어떤 서버에서 메트릭을 가져올지를 job 단위로 설정한다. 각 job에는 metrics_path, scrapte_interval, targets 등이 정의 된다.
3. job_name: 'prometheus'
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: ['prometheus:9090']
프로메테우스가 어떤 서버에서 메트릭을 가져올지를 job 단위로 설정한다.
- job_name: 'prometheus': Prometheus 자기 자신을 모니터링하기 위한 job
- scrape_interval: 5s: 이 job에 대해서만 5초 간격으로 메트릭을 수집
- targets: ['prometheus:9090']:
- Docker Compose 나 네트워크 내에서 prometheus라는 호스트 이름으로 실행되는 Prometheus 서버를 가리키며, 9090 포트는 Prometheus의 기본 포트이다.
- Prometheus 자신이 /metrics 엔드포인트로 메트릭을 노출하므로, 이를 통해 Prometheus의 상태와 성능을 모니터링 가능하다.
4. job_name: 'grafana'
- job_name: 'grafana'
scrape_interval: 5s
static_configs:
- targets: ['grafana:3000']
- job_name: 'grafana': Grafana를 모니터링하기 위한 job
- scrape_interval: 5s: 5초 간격으로 Grafana 메트릭을 수집
- targets: ['grafana:3000']:
- Docker Compose나 네트워크 내에서 grafana라는 호스트 이름, 3000 포트를 사용.
- Grafana가 /metrics 등 특정 엔드포인트에서 Prometheus 형식으로 메트릭을 노출한다면, 이를 통해 Grafana의 상태 및 성능을 모니터링할 수 있음
5. job_name: 'prod_app_server'
- job_name: 'prod_app_server' # {PORT}에 대한 App Name
metrics_path: '/actuator/prometheus'
scrape_interval: 15s
static_configs:
- targets:
- '{SERVER_ADDRESS}:{PORT}'
labels:
app_name: 'prod_app_server'
- job_name: 'prod_app_server': 프로덕션 환경에서 동작 중인 App Server(애플리케이션) 모니터링 job
- metrics_path: '/actuator/prometheus': Spring Boot Actuator + Micrometer Prometheus 연동 시, 메트릭을 노출하는 기본 엔드포인트
- scrape_interval: 15s: 이 job에 대해서는 15초 간격으로 메트릭을 수집
- targets: ['{SERVER_ADDRESS}:{PORT}']: 수집할 서버의 주소 및 포트
- labels: { app_name: 'prod_app_server' }:
- 수집되는 메트릭에 app_name="prod_app_server"라는 라벨을 추가
- Grafana 등에서 메트릭을 구분하거나 필터링할 때 사용
6. job_name: 'prod_owner_server'
- job_name: 'prod_owner_server' # {PORT}에 대한 App Name
metrics_path: '/actuator/prometheus'
scrape_interval: 15s
static_configs:
- targets:
- '{SERVER_ADDRESS}:{PORT}'
labels:
app_name: 'prod_owner_server'
- job_name: 'prod_owner_server': 프로덕션 환경에서 동작 중인 Owner Server(또 다른 Spring Boot 애플리케이션 등) 모니터링 job
- metrics_path: '/actuator/prometheus': 마찬가지로 Actuator Prometheus 엔드포인트에서 메트릭을 노출.
- scrape_interval: 15s: 15초 간격으로 메트릭을 수집.
- targets: ['{SERVER_ADDRESS}:{PORT}']: 수집할 서버의 주소 및 포트
- labels: { app_name: 'prod_owner_server' }:
- 수집되는 메트릭에 app_name="prod_owner_server"라는 라벨을 추가
- Grafana 등에서 메트릭을 구분하거나 필터링할 때 사용
📌 Spring Actuator
application.yml 파일에 프로메테우스가 수집할 수 있도록 노출 시킬 엔드포인트들을 설정할 수 있는데, 각각 /actuator/loggers, /actuator/prometheus, /actuator/health 를 통해 노출된 엔드포인트로 정보들을 확인할 수 있다.
(노출된 엔드포인트는 민감한 정보가 담길 수 있으므로 반드시 프로메테우스만 접근할 수 있도록 보안을 신경써줘야 한다.)
Visualizing Prometheus in Grafana
이제 Prometheus와 Actuator를 통한 모니터링 시스템은 구축이 완료되었다. 그렇다면 실행중인 애플리케이션의 실시간 모니터링을 Grafana에서 확인해보자. 이전 게시글과 마찬가지로 대시보드를 만드는 과정은 생략하겠다.
나는 실시간 API 모니터링 대시보드와 JVM 모니터링 대시보드를 총 2가지를 구성했다.
먼저 API 모니터링 시스템을 살펴보면 간단하게 API별 평균 응답속도, 총 요청 수, 예외 발생수, API별 요청수 등을 구성하였다.
그리고 두번째 JVM 모니터링 시스템을 살펴보면 JVM에 대해 수집된 메트릭 정보들을 시각화 하였다.
간단하게 CPU 사용량과 HTTP 요청에 대한 간략 정보들을 확인할 수 있다.
또한 실행중인 애플리케이션의 JVM의 메모리 사용량도 모니터링 할 수 있어 OOM 문제를 방지하거나 사전에 발견할 수 있지 않을까라는 기대감이 있다.
'DevOps > Monitoring' 카테고리의 다른 글
PLG Stack(Promtail, Loki, Grafana)으로 효과적인 로그 모니터링 시스템 구축하기 (0) | 2025.01.29 |
---|---|
로그 시스템이 필요한가요? (ELK Stack과 PLG Stack) (0) | 2025.01.25 |