코딩 이래요래
Spring Boot + Prometheus + Grafana 대시보드 만들기 본문
1. 프로메테우스(Prometheus)?
- 시간의 흐름에 따라 변동 되는 데이터를 메트릭(Metric)이라고 한다.
- SpringBoot는 Actuator가 metric 수집을 담당하고 있다.
- 문제는, 메트릭은 시간이 흐를수록 대량의 데이터가 쌓이는데 Application의 메모리만으로 metric의 데이터를 모두 감당할 수 없다.
- 이때, 시계열 데이터베이스(Time Series Database)인 프로메테우스를 사용하여 데이터를 저장한다.
SpringBoot에서는 Actuator 엔드포인트의 접근 권한을 설정할 수 있어, 일반 사용자와 Prometheus와 같은 외부 시스템의 접근 경로를 분리할 수 있다.
예를 들어 /actuator/health, /actuator/info는 공개하고, /actuator/prometheus는 Prometheus만 접근할 수 있도록 제한할 수 있다.
Prometheus는 이 엔드포인트를 통해 Actuator가 수집한 메트릭 정보를 일정 주기로 pull 방식으로 가져간다.
이제 프로메테우스를 연동시켜 보자
1. 프로메테우스 설치
Download | Prometheus
Downloads for the latest releases of the Prometheus monitoring system and its major ecosystem components.
prometheus.io
- 해당 링크로 접속 후 다운로드
- 프로메테우스를 설치하고 터미널을 열어 설치한 폴더로 이동 후 프로메테우스 서버를 실행한다.
- 명령어 ./prometheus
2. 서버 실행 확인
- localhost:9090으로 접속 후 해당 화면이 열리면 프로메테우스 서버가 실행된 것.
3. SpringBoot 설정
build.gradle
- actuator와 prometheus 의존성을 추가한다.
application.yml
- actuator는 민감한 정보를 포함하고 있기 때문에 개발 환경에서만 *로 설정해야 한다.
대시보드에 필요한 Metric 설정
@Component
public class LibraryMetrics {
private static final Logger log = LoggerFactory.getLogger(LibraryMetrics.class);
private final MeterRegistry meterRegistry;
private final BookRepository bookRepository;
private final MemberRepository memberRepository;
private final LoanRepository loanRepository;
private final ReviewRepository reviewRepository;
// 카운터 메트릭
private Counter bookCreatedCounter;
private Counter loanCreatedCounter;
private Counter reviewCreatedCounter;
private Counter errorCounter;
// 타이머 메트릭
private Timer bookSearchTimer;
private Timer loanProcessTimer;
// 게이지용 원자적 변수
private final AtomicLong totalBooksGauge = new AtomicLong(0);
private final AtomicLong activeMembersGauge = new AtomicLong(0);
private final AtomicLong activeLoanGauge = new AtomicLong(0);
@Autowired
public LibraryMetrics(MeterRegistry meterRegistry, BookRepository bookRepository,
MemberRepository memberRepository, LoanRepository loanRepository,
ReviewRepository reviewRepository) {
this.meterRegistry = meterRegistry;
this.bookRepository = bookRepository;
this.memberRepository = memberRepository;
this.loanRepository = loanRepository;
this.reviewRepository = reviewRepository;
}
@PostConstruct
public void initMetrics() {
log.info("[s4][LibraryMetrics] 도서관 시스템 커스텀 메트릭 초기화 시작");
// 카운터 메트릭 초기화
bookCreatedCounter = Counter.builder("library.books.created")
.description("생성된 도서 수")
.tag("system", "library")
.register(meterRegistry);
loanCreatedCounter = Counter.builder("library.loans.created")
.description("생성된 대출 수")
.tag("system", "library")
.register(meterRegistry);
reviewCreatedCounter = Counter.builder("library.reviews.created")
.description("생성된 리뷰 수")
.tag("system", "library")
.register(meterRegistry);
errorCounter = Counter.builder("library.errors.total")
.description("발생한 오류 수")
.tag("system", "library")
.register(meterRegistry);
// 타이머 메트릭 초기화
bookSearchTimer = Timer.builder("library.books.search.duration")
.description("도서 검색 소요 시간")
.tag("system", "library")
.register(meterRegistry);
loanProcessTimer = Timer.builder("library.loans.process.duration")
.description("대출 처리 소요 시간")
.tag("system", "library")
.register(meterRegistry);
// 게이지 메트릭 초기화
Gauge.builder("library.books.total", this, LibraryMetrics::getTotalBooks)
.description("전체 도서 수")
.tag("system", "library")
.register(meterRegistry);
Gauge.builder("library.members.active", this, LibraryMetrics::getActiveMembers)
.description("활성 회원 수")
.tag("system", "library")
.register(meterRegistry);
Gauge.builder("library.loans.active", this, LibraryMetrics::getActiveLoans)
.description("활성 대출 수")
.tag("system", "library")
.register(meterRegistry);
Gauge.builder("library.reviews.total", this, LibraryMetrics::getTotalReviews)
.description("전체 리뷰 수")
.tag("system", "library")
.register(meterRegistry);
// 초기 데이터 로드
updateGaugeMetrics();
log.info("[s4][LibraryMetrics] 도서관 시스템 커스텀 메트릭 초기화 완료");
}
// 도서 생성 카운트 증가 메서드..
// 도서 대출 생성 카운드 증가 메서드..
...
}
4. 프로메테우스 데이터 포맷의 메트릭 데이터 확인
- http://localhost:8080/actuator/prometheus로 접속하면 직접 추가한 Metric 데이터를 확인할 수 있다.
- SpringBoot는 micrometer 라이브러리를 통해 수집된 메트릭을 Actuator에 노출하고, 프로메테우스는 /actuator/prometheus 엔드포인트를 통해 해당 메트릭을 pull 방식으로 주기적으로 수집한다.
- 이때 Micrometer가 Prometheus에서 이해할 수 있는 형식으로 데이터를 출력 해주며 이를 위해 아래 의존성을 추가한 것이다.
- implementation 'io.micrometer:micrometer-registry-prometheus'
5. 프로메테우스로 데이터 가져오기
- prometheus.yaml 파일을 열어 아래 설정을 추가한다.
- job_name: "spring-actuator"
metrics_path: '/actuator/prometheus'
scrape_interval: 1s
static_configs:
- targets: ['localhost:8080']
- scrape_interval을 1초로 설정하여, metrics_path의 경로로 메트릭 데이터를 1초마다 접근하여 데이터를 수집한다.
6. 프로메테우스 연동 확인
- Status -> Target health 이동
- 아까 등록한 spring-actuator가 State UP 상태로 보인다면 연동이 완료된 것을 확인할 수 있다.
7. Metric 데이터 시각화 하기
그라파나(Grafana)?
- 프로메테우스로 수집한 metric 데이터를 시각화하는데 특화된 툴(tool)이다.
Download Grafana | Grafana Labs
Overview of how to download and install different versions of Grafana on different operating systems.
grafana.com
- 위 링크를 통해 Grafana를 설치한다.
- 설치 후 bin 폴더로 이동하여 Grafana 서버를 실행한다.
- ./grafana-server
- localhost:3000 접속하면 로그인 창이 뜰텐데 admin/admin 으로 로그인하면 해당 화면이 열리면 서버가 정상적으로 동작중이다.
- Add new connections를 클릭하여 프로메테우스와 그라파나를 연동해야한다.
- 검색을 통해 프로메테우스를 클릭하여 새로운 커넥션을 만든다.
- URL에 프로메테우스 로컬서버 주소인 http://localhost:9090을 입력하고 저장한다.
- 대시보드 탭을 클릭하여 새로운 대시보드를 만들어 준다.
- 아래 Select metric에 프로메테우스에서 가져온 데이터중 원하는 데이터를 입력후 Run queries를 클릭하면 panel에 시각화된 데이터가 표시된다.
대시보드 테스트
'JAVA' 카테고리의 다른 글
Spring Data JPA (1) | 2025.05.30 |
---|---|
Spring Framework 핵심 개념 (0) | 2025.04.29 |
자료구조 - Tree, Binary Tree (0) | 2025.04.16 |
자료구조 - Stack, Queue, Deque (0) | 2025.04.13 |
자료구조 - List (0) | 2025.04.13 |