안녕세계
[Spring] 그라파나와 프로메테우스로 애플리케이션 모니터링하기 본문
[Spring] 그라파나와 프로메테우스로 애플리케이션 모니터링하기
Junhong Kim 2023. 4. 9. 15:25액츄에이터(Actuator)
서비스 운영시에는 서비스에 문제가 없는지 모니터링할 수 있는 metric(지표)을 추가하여 감사(auditing)가 필요합니다. 이처럼 서비스 모니터링에 필요한 metric을 스프링부트 액츄에이터(SpringBoot Actuator)를 사용하면 손 쉽게 확인할 수 있습니다. 그리고 액츄에이터는 마이크로미터(micrometer), 프로메테우스(Prometheus), 그라파나(Grafana)와 같은 모니터링 시스템과 연동할 수 있는 기능도 함께 제공하고 있습니다.
액츄에이터가 제공하는 기능을 사용하기 위해서는 라이브러를 먼저 추가해야합니다.
implementation("org.springframework.boot:spring-boot-starter-actuator")
라이브러리를 추가한 뒤 서버를 실행하여 `/actuator`로 접속해보면 액츄에이터가 제공하는 기능을 확인할 수 있습니다.
{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"health-path": {
"href": "http://localhost:8080/actuator/health/{*path}",
"templated": true
},
"health": {
"href": "http://localhost:8080/actuator/health",
"templated": false
}
}
}
이외에도 액츄에이터 설정에서 특정 기능을 노출(exposure)하면 수정하면 추가적인 기능들을 확인할 수 있습니다.
management:
endpoint:
shutdown:
enabled: true # shutdown 엔드포인트 활성화
endpoints:
web: # web에 엔드포인트 노출
exposure:
include: "*" # 모든 엔드포인트 노출
각 엔드포인트는 `/actuator/{endpoint}` 형식으로 접근할 수 있으며, 해당 엔드포인트를 사용하려면 활성화와 노출이라는 설정이 필요합니다.
- 엔드포인트 활성화란? 기능을 사용하지 여부를 설정하는 것
- 엔드포인트 노출이란? 활성화된 엔드포인트를 WEB에 노출할지 JMX를 통해서 노출할지 설정하는 것
즉, 엔드포인트를 활성화 후 WEB 또는 JMX를 통해 노출하거나 두 위치에 모두 노출할지 설정해야합니다.
(참고: 엔드포인트가 활성화되어 있지 않으면 노출도 되지 않습니다.)
엔드포인트는 대부분 기본적으로 활성화 상태이기 때문에 노출 위치만 선택하면 됩니다. 따라서, 위에서 말한 것처럼 WEB과 JMX를 선택할 수 있는데 보통은 접근성이 좋은 WEB에 엔드포인트를 노출하도록 설정합니다.
(참고: shutdown은 기본 값이 비활성화입니다.)
액츄에이터가 제공하는 기능은 애플리케이션 내부 정보를 많이 노출하기 때문에 외부로 공개된 환경에서 액츄에이터 엔드포인트를 공개하는 것은 지양해야합니다. 따라서, 액츄에이터 엔드포인트는 외부에서 접근이 불가능하도록 막고 내부에서만 접근할 수 있는 내부망을 사용하는 것을 권장합니다. 다음과 같이 애플리케이션 접근 포트와 별개로 액츄에이터 접근 포트를 변경할 수 있습니다.
management:
server:
port: 9292 # `http://localhost:9292/actuator`로 액츄에이터 포트 변경
마이크로미터(Micrometer)
그라파나, 핀포인트와 같은 모니터링 툴이 동작하기 위해서는 metric을 각 모니터링 툴이 이해할 수 있는 포맷으로 맞추어 보내줘야합니다. 그런데 새로운 모니터링 툴을 사용할 때마다 포맷을 맞춰 모니터링 툴로 보내줘야한다는 것은 생각만해도 번거로운 일입니다. 따라서, 이러한 문제를 해결하기 위해서 우리는 마이크로미터라는 라이브러리를 사용합니다.
마이크로미터는 Application Metric Facade라고 불리며 애플리케이션 metric을 마이크로미터가 정한 표준 방법으로 모아서 제공하게 됩니다. 따라서, 개발자는 마이크로미터가 정한 표준 방법으로 메트릭을 전달하고 사용하는 모니터링 툴에 맞는 구현체를 사용하면 됩니다. 마이크로미터가 지원하는 모니터링 툴은 여기에서 확인할 수 있습니다.
마이크로미터는 metric 수집 기능을 이미 만들어서 제공하며 액츄에이터는 마이크로미터가 제공하는 metric 수집 기능을 `@AutoConfiguration`을 통해 자동으로 등록해줍니다. 액츄에이터의 metrics 엔드포인트 `/actuator/metrics`로 접속하면 기본으로 제공되는 metric을 확인할 수 있습니다.
{
"names": [
"application.ready.time",
"application.started.time",
"disk.free",
"disk.total",
"executor.active",
"executor.completed",
"executor.pool.core",
"executor.pool.max",
"executor.pool.size",
"executor.queue.remaining",
"executor.queued",
"hikaricp.connections",
"hikaricp.connections.acquire",
"hikaricp.connections.active",
"hikaricp.connections.creation",
"hikaricp.connections.idle",
"hikaricp.connections.max",
"hikaricp.connections.min",
...
}
프로메테우스와 그라파나
프로메테우스(Prometheus)
액츄에이터 엔드포인트를 접속할 때마다 그 시점의 metric을 확인할 수 있는데, 우리는 접속 시점의 metric 뿐만 아니라 서비스 운영을 위해 과거 metric도 필요합니다. 그렇다면 과거 metric을 보관할 수 있는 DB가 필요한데 프로메테우스가 metric을 지속적으로 수집하고 DB에 저장하는 역할을 해줍니다.
(참고: `/actuator/metrics/jvm.memory.used`)
그라파나(Grafana)
프로메테우스로 수집한 metric 데이터를 시각화할 수 있는 대시보드가 필요한 경우 데이터를 시각화해주는 툴을 사용해야합니다. 이때 많이 사용되고 있는 툴으로는 그라파나가 있으며 그라파는 프로메테우스가 수집한 데이터를 시각화하여 보여줄 수 있습니다. 또한, 그라파나는 프로메테우스 외에도 다양한 데이터 소스(예: 로키)를 대시보드로 확인할 수 있도록 지원하고 있습니다.
프로메테우스 설치
그럼 프로메테우스를 로컬 PC에 설치하고 metric을 수집해보겠습니다. 프로메테우스는 여기에서 다운 받을 수 있으며 MacOS 사용자는 `darwin-amd64`를 다운받으면 됩니다. 다운 받은 후 압축을 풀면 다음과 같은 파일들이 있습니다.
/
├ console_libraries
├ consoles
├ data
├ LICENSE
├ NOTICE
├ prometheus # 실행
├ prometheus.yml
└ promtool
터미널로 접속해서 `./prometheus`를 실행하면 `localhost:9090`에 프로메테우스가 실행된 것을 확인할 수 있습니다.
프로메테우스는 앞서 소개한 것 처럼 metric을 수집하고 저장하는 DB입니다. 따라서, 프로메테우스가 우리 애플리케이션의 metric을 수집하도록 연동해야합니다. 이때, 애플리케이션과 프로메테우스에 설정이 필요합니다.
- 애플리케이션 설정: 프로메테우스가 애플리케이션의 metric을 가져갈 수 있도록 애플리케이션에서 프로메테우스 포맷에 맞추어 metric을 만들어 둬야 합니다. (마이크로미터를 사용하면 될 것 같은 느낌이 드시나요? 😆)
- 프로메테우스 설정: 프로메테우스가 애플리케이션의 metric을 주기적으로 수집하도록 설정해야 합니다.
애플리케이션 설정
프로메테우스가 애플리케이션 metric을 가져가려면 프로메테우스가 원하는 포맷에 맞춰 metric을 생성해야합니다. 근데 우리는 이미 액츄에이터에 의해서 `/actuator/metric`로 접속하면 기본적인 metric이 생성되고 있는 것을 알고 있습니다. 위 경로로 접속해보면 json 형식의 metric 데이터가 존재하는 것을 확인할 수 있습니다.
안타깝게도 프로메테우스는 json 형식의 metric 데이터를 이해할 수 없습니다. 따라서, 우리는 프로메테우스가 이애할 수 있는 포맷으로 metric을 변경해야합니다. 다행히도 우리는 마이크로미터를 사용해서 프로메테우스가 이해할 수 있는 포맷으로 손 쉽게 변환할 수 있습니다. 마이크로미터가 어떤 구현체를 사용할지만 지정하면 프로메테우스를 위한 metric을 만들어낼 수 있습니다.
애플리케이션에 마이크로미터 프로메테우스 구현 라이브러리를 추가해봅시다.
implementation("io.micrometer:micrometer-registry-prometheus") // 프로메테우스 마이크로미터
위 구현체를 등록하면 스프링 부트 액츄에이터가 metric 수집을 `@AutoConfiguration`을 통해 자동으로 등록해줍니다. 이제 애플리케이션을 재실행하면 `/actuator`에 기존에 없었던 `/actuator/prometheus` 엔드포인트가 추가된 것을 확인할 수 있습니다. 이 경로에서 확인할 수 있는 데이터가 바로 프로메테우스가 metric을 수집할 때 이해할 수 있는 포맷입니다.
# HELP hikaricp_connections_usage_seconds Connection usage time
# TYPE hikaricp_connections_usage_seconds summary
hikaricp_connections_usage_seconds_count{pool="HikariPool-1",} 4.0
hikaricp_connections_usage_seconds_sum{pool="HikariPool-1",} 0.0
# HELP hikaricp_connections_usage_seconds_max Connection usage time
# TYPE hikaricp_connections_usage_seconds_max gauge
hikaricp_connections_usage_seconds_max{pool="HikariPool-1",} 0.0
# HELP jdbc_connections_idle Number of established but idle connections.
# TYPE jdbc_connections_idle gauge
jdbc_connections_idle{name="dataSource",} 10.0
# HELP jvm_classes_loaded_classes The number of classes that are currently loaded in the Java virtual machine
# TYPE jvm_classes_loaded_classes gauge
jvm_classes_loaded_classes 11965.0
# HELP system_cpu_usage The "recent cpu usage" of the system the application is running in
# TYPE system_cpu_usage gauge
system_cpu_usage 0.22846441947565543
# HELP jdbc_connections_min Minimum number of idle connections in the pool.
# TYPE jdbc_connections_min gauge
jdbc_connections_min{name="dataSource",} 10.0
# HELP hikaricp_connections_idle Idle connections
# TYPE hikaricp_connections_idle gauge
hikaricp_connections_idle{pool="HikariPool-1",} 10.0
...
프로메테우스 설정
액츄에이터 엔드포인트로 프로메테우스가 이해할 수 있는 metric을 생성하고 있으니 이제 프로메테우스가 해당 metric을 주기적으로 수집할 수 있도록 설정해보겠습니다. 프로메테우스 설정은 프로메테우스 실행 파일이 있는 디렉토리로 이동해서 `prometheus.yml` 파일을 수정해야합니다. job_name이 `spring-actuator`인 설정을 추가해봅시다.
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
# 추가 설정
- job_name: "spring-actuator"
metrics_path: '/actuator/prometheus'
scrape_interval: 1s
static_configs:
- targets: ['localhost:8080']
- job_name: job 이름 (임의의 이름 사용)
- metrics_path: metric을 수집할 경로
- scrape_interval: metric을 수집할 주기 (기본 값: 1m)
- 수집 주기가 너무 짧으면 애플리케이션 성능에 영향을 줄 수 있으므로 실제 운영환경에서는 10s~1m를 권장합니다.
- targets: 수집할 서버의 <IP:PORT>
위 설정 후 프로메테우스 서버를 종료하고 재실행합니다. 이제 프로메테우스는 `/actuator/prometheus`로부터 1초에 한번씩 호출해서 애플리케이션의 metric을 수집하도록 설정이 완료되었습니다.
프로메테우스 연동 확인
1. `http://localhost:9090/config`로 접속해서 `prometheus.yml`에 입력한 내용이 추가되었는지 확인합니다.
2. `http://localhost:9090/targets`로 접속해서 spring-actuator가 잘 연동되었는지 확인합니다.
- prometheus: 프로메테우스 자체에서 제공하는 메트릭 정보 (프로메테우스 자신의 메트릭을 확인하는 것)
- spring-actuator: 우리가 연동한 애플리케이션의 메트릭 정보, state가 up 상태이면 정상입니다.
이상으로 프로메테우스를 설치하고 연동하는 방법에 대해 알아봤습니다.
프로메테우스와 관련된 문법들은 본 포스팅에서는 다루지 않으므로 다음 공식 문서를 확인해주세요.
- 기본 문법: https://prometheus.io/docs/prometheus/latest/querying/basics/
- 연산자: https://prometheus.io/docs/prometheus/latest/querying/operators/
- 함수: https://prometheus.io/docs/prometheus/latest/querying/functions/
그라파나 설치
여기로 접속해서 그라파나를 다운로드합니다. MacOS 사용자는 darwin-amd64를 설치하시면 됩니다.
다운 받은 후 압축을 풀면 다음과 같은 파일들이 있습니다.
┌ LICENSE
├ NOTICE.md
├ README.md
├ VERSION
├ bin
│ ├ grafana
│ ├ grafana-cli
│ ├ grafana-cli.md5
│ ├ grafana-server # 실행
│ ├ grafana-server.md5
│ └ grafana.md5
├ conf
├ data
├ plugins-bundled
└ public
터미널에서 `./bin/grafana-server`를 실행하면 `localhost:3000`에 그라파나가 실행된 것을 확인할 수 있습니다.
username과 password에 `admin`을 입력하면 접속할 수 있습니다.
그라파나는 앞서 소개한 것처럼 프로메테우스를 통해서 데이터를 조회해서 시각화하는 역할을 합니다. 따라서, 그라파나에서 프로메테우스 데이터 소스를 사용해서 데이터를 읽어볼 수 있도록 수정해합니다. 그라파나가 프로메테우스 데이터 소스를 읽을 수 있도록 수정해봅시다. `Configuration > Data sources` 메뉴에 접근해서 `Add data source`를 클릭해주세요.
다양한 데이터 소스가 있는데 우리는 프로메테우스를 선택합니다.
프로메테우스가 실행되고 있는 주소를 설정한 뒤 다른 설정은 그대로 두고 저장합니다.
그라파나의 데이터 소스로 프로메테우스를 설정했으니 이제 그라파나는 프로메테우스에 저장되어있는 metric을 조회할 수 있습니다. 그라파나는 데이터를 시각화 할 수 있는 툴이기 때문에 대시보드와 패널을 추가해서 데이터를 시각화해봅시다.
jvm_memory_used_bytes{area=~"heap|nonheap",instance="localhost:8080",job="spring-actuator"}
PromQL을 사용해서 직접 쿼리를 작성할 수도 있지만, Metric browser를 사용해서 쿼리 문법을 자동으로 생성할 수도 있습니다.
예제 패넬에서는 JVM Memory 사용량을 확인하는 쿼리를 작성하고 타이틀을 지정한 뒤 apply 했습니다.
New dashboard에 JVM Memory Usage를 추가된 것을 확인할 수 있습니다. 처럼 확인하고 싶은 애플리케이션 metric을 그라파나 대시보드 패널로 추가할 수 있습니다. 또한, 그라파나는 시각화해주는 것 뿐만 아니라 애플리케이션 상태가 특정 상태에 도달할 때 자동으로 Slack, Opsgenine 등으로 알람을 해주는 기능도 있습니다. (본 포스팅에서는 PromQL과 알람 설정에 대한 내용은 다루지 않습니다.)
요약
지금까지 액츄에이터, 마이크로미터, 프로메테우스, 그라파나의 관계에 대해 알아보았으며 애플리케이션 모니터링에 필요한 툴을 설치하고 데이터 시각화를 해보았습니다. 본 포스팅에서 진행한 내용을 요약하자면 다음과 같으며 이번 포스팅으로 프로메테우스와 그라파나에 대한 궁금증이 해결되셨으면 좋겠습니다. 👋
- 스프링부트 액츄에이터(SpringBoot Actuator)를 사용해서 metric을 생성
- 프로메테우스가 이해할 수 있는 metric 포맷을 만들기 위해 마이크로미터(Micrometer)를 사용
- 마이크로미터에 의해 만들어진 metric 데이터를 프로메테우스(Prometheus)가 지속적으로 수집
- 그라파나(Grafana)에 프로메테우스 데이터 소스 매핑
- 애플리케이션 metric을 그라파나 대시보드 패널로 시각화
참고
'Server > Spring' 카테고리의 다른 글
[Spring] JPA 성능 최적화 (0) | 2023.05.06 |
---|---|
[Spring] 그라파나와 로키로 애플리케이션 로그 조회하기 (0) | 2023.04.22 |
[Spring] EventListener vs TransactionalEventListener (0) | 2023.03.08 |
[Spring] MyBatis API 개발 예제 (0) | 2020.09.27 |
[Spring] MyBatis 데이터베이스 연동 (0) | 2020.09.26 |