애플리케이션의 메트릭과 상태를 모니터링하는 것은 성능을 개선하고, 앱을 더 나은 방식으로 관리하고, 최적화되지 않은 동작을 발견하는 데 도움이 됩니다. 많은 마이크로서비스로 구성된 시스템을 유지 관리하려면 각 서비스를 모니터링하는 것이 중요합니다. 애플리케이션의 메트릭을 노출하는 Micrometer, 메트릭 데이터를 저장하는 Prometheus, 데이터를 그래프로 시각화하는 Grafana를 사용하여 Spring Boot 웹 애플리케이션을 로컬에서 모니터링하고자 합니다.

Grafana를 사용하려면
먼저 Spring Actuator를 이용해 현재 애플리케이션의 상태를 HTTP API로 응답할 수 있게 설정합니다. 
Prometheus를 이용하여 Spring Actuator에서 제공하는 메트릭 데이터를 수집합니다.
Grafana를 이용하여 메트릭 데이터를 시각화하여 볼 수 있게됩니다.

  • Spring Actuator: Spring Boot 애플리케이션을 모니터링하고 관리하기 위한 여러 엔드포인트를 제공하는 Spring Boot의 기능입니다. 여기에는 애플리케이션의 상태, 메트릭 및 기타 정보를 모니터링하기 위한 기본 제공 엔드포인트가 포함되어 있습니다. 이러한 엔드포인트는 HTTP를 통해 액세스할 수 있으므로 다른 도구 및 시스템과 쉽게 통합할 수 있습니다.
  • Micrometer: Spring Boot 애플리케이션을 포함한 Java 애플리케이션을 위한 메트릭 수집 라이브러리입니다. 다양한 소스에서 메트릭을 수집하고 다양한 방식으로 확인하기 위한 간단한 API를 제공합니다. (Spring 5부터 Spring의 메트릭은 Micrometer에서 처리됩니다.)
  • Prometheus: 메트릭 데이터를 수집하고 저장하는 데 사용할 수 있는 모니터링 시스템입니다.
  • Grafana: 메트릭 데이터의 대시보드와 시각화를 만드는 데 사용할 수 있는 오픈소스 데이터 시각화 도구입니다.

 

Micrometer

Micrometer는 가장 널리 사용되는 모니터링 시스템의 계측 클라이언트에 대해 간단한 인터페이스를 제공하여 공급업체 종속 없이 JVM 기반 애플리케이션 코드를 계측할 수 있도록 합니다. 또한 Micrometer 는 오픈소스 프로젝트이며 모니터링 시스템이 이해할 수 있는 벤더 중립적 형식으로 메트릭 데이터를 노출하는 Metric Facade를 제공합니다. Micrometer는 아래와 같은 모니터링 시스템과 연동할 수 있습니다.

  • Azure Monitor
  • CloudWatch
  • Datadog
  • Elastic
  • Ganglia
  • Graphite
  • Prometheus
  • Google Stackdriver

하지만 Micrometer는 Spring 생태계의 일부가 아니므로 종속성을 아래와 같이 추가해야 합니다. 

implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-web")
runtimeOnly("io.micrometer:micrometer-registry-prometheus")

그리고 application.yml에 아래와 같은 설정을 추가합니다.

management:
  endpoints:
    web:
      exposure:
        include: health, info, metrics, prometheus

 

이제 Spring Boot 애플리케이션 프로젝트에서 아래와 같은 HTTP API를 제공합니다.

  • /actuator : Actuator가 제공하는 URL을 볼 수 있습니다.
  • /actuator/metrics : 메트릭 목록을 보여줍니다.
  • /actuator/prometheus : Micrometer를 통해 수집된 metric들을 볼 수 있습니다.

각 엔트포인트별 설명은 docs.spring.io 혹은 Spring Boot Actuator에서 확인할 수 있습니다.

http://localhost:8080/actuator/prometheus

 

Prometheus

Prometheus는 주기적으로 Spring Actuator에서 제공하는 HTTP API를 통해 메트릭 데이터를 가져와서 시간대 별로 저장합니다. 이 데이터는 Grafana에서 통합해서 시각화할 수 있습니다. Prometheus는 Docker 컨테이너로 로컬에서 띄울 수 있습니다. 따라서 docker-compose.yml 파일과 Prometheus 옵션을 지정할 수 있는 prometheus.yml 파일을 설정해야합니다.

global:
    scrape_interval: 1s  # 스크랩 시간 간격을 5초로 설정
    evaluation_interval: 1s # 판별 규칙 시간을 5초로 구성

scrape_configs:
    -   job_name: 'spring-boot-application'
        metrics_path: '/actuator/prometheus'
        static_configs:
            -   targets: [ 'host.docker.internal:8080' ]
// docker-compose.yml
prometheus:
    image: prom/prometheus:latest
    ports:
        - "9090:9090"
    volumes:
        - ./prometheus.yml:/etc/prometheus/prometheus.yml
    container_name: prometheus

prometheus.yml에서 사용 가능한 모든 옵션은 공식 문서에서 확인할 수 있습니다.

Docker 컨테이너에서 prometheus를 실행하려면 static_configs.targets에 localhost 대신 IP 주소를 Prometheus에 알려주어야 합니다. 따라서 localhost:8080 대신 host.docker.internal:8080 값을 사용합니다. 이 경우 구성 파일이 Prometheus 컨테이너에 매핑될 때 macOS의 컨테이너에서 호스트가 확인되도록 하는 특수 도메인 localhost 대신 host.docker.internal을 사용할 수 있습니다.

이제 http://localhost:9090에서 Prometheus를 확인할 수 있습니다. 프로메테우스 상단 메뉴에서 status -> Targets 로 이동했을 때 Spring Boot 애플리케이션을 제대로 수신하고 있는지 확인할 수 있습니다.

Prometheus는 PromQL이라는 쿼리 언어를 제공하며, 자세한 내용은 공식 문서를 참조하시기 바랍니다.

 

Grafana

Prometheus에서 제공하는 메트릭의 그래프도 시각화에 유용하지만, 널리 사용되는 Grafana를 사용해보겠습니다. Grafana는 여러 그래프를 사용하는 대시보드를 생성할 수 있고 다양한 탐색과 공유기능 등 풍부한 UI를 제공합니다.

Grafana는 Prometheus, ElasticSearch, InfluxDB 등과 같은 다양한 데이터베이스(DataSource)에서 데이터를 받아 시각화할 수 잇습니다. 또한 규칙 기반 알림을 지정할 수 있으며 Slack, Email 등을 통해 사용자에게 알릴 수 있습니다.

아래와 같이 docker-compose.yml 파일에 설정했을 떄 로컬에서 Grafana를 docker contianer로 생성할 수 있습니다.

grafana:
    image: "grafana/grafana:latest"
    ports:
        - "3000:3000"
    environment:
        - GF_SECURITY_ADMIN_USER=admin # 사용자 이름 설정
        - GF_SECURITY_ADMIN_PASSWORD=admin # 사용자 비밀번호 설정
    container_name: grafana

이제 Prometheus, Micrometer, Grafana를 전부 docker-compose.yml에 추가하였으니 실행해보겠습니다.

$ docker-compose up

 

주소 http://localhost:3000 에 접속했을 때 아래와 같이 Grafana 로그인 페이지가 보일 것 입니다.

docker-compose Grafana에서 설정했듯이 admin/admin 아이디와 패스워드로 로그인할 수 있습니다.

이제는 로컬에 존재하는 Prometheus에 메트릭 데이터가 저장되어 있는 데이터베이스(DataSource)를 추가하는 것입니다. 

http://host.docker.internal:9090

그리고 추가하려는 대시보드는 그라파나 유저들이 공유하는 community dashboard입니다. 우리는 Spring Boot 애플리케이션을 사용하고 있으므로 널리 사용되는 JVM dashboard를 선택하고자 합니다.

https://grafana.com/grafana/bashboards/4701

URL을 로드하면 import한 대시보드를 로드할 수 있습니다.

애플리케이션의 메트릭을 노출하는 Micrometer,
메트릭 데이터를 저장하는 Prometheus,
데이터를 그래프로 시각화하는 Grafana

애플리케이션의 메트릭과 상태를 모니터링하는 것은 성능을 개선하고, 앱을 더 나은 방식으로 관리하고, 최적화되지 않은 동작을 발견하는 데 도움이 됩니다. 많은 마이크로서비스로 구성된 시스템을 유지 관리하려면 각 서비스를 모니터링하는 것이 중요합니다.