📌 Spring Boot 모니터링 통합 실습: Prometheus, AlertManager, Grafana, Slack 연동
0. 사전 설정: Micrometer 기반 사용자 정의 메트릭 노출
package org.example.bootfromcompose;
import io.micrometer.core.annotation.Counted;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CountedController {
@Counted(
value = "give_me_money",
description = "부자가 되고 싶어요")
@GetMapping("/counted")
public String getCounted() {
return "Counted OK";
}
@GetMapping("/error")
public ResponseEntity<Void> getError() {
return ResponseEntity.status(500).build();
}
}
- /counted: 호출 시 give_me_money_total이라는 메트릭을 1씩 증가
1. application.yml 설정
spring:
application:
name: boot-from-compose
management:
endpoints:
web:
exposure:
include: "health,prometheus"
prometheus:
metrics:
export:
enabled: true
2. Prometheus 설정 (prometheus.yml)
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'spring-boot-app'
static_configs:
- targets: ['host.docker.internal:8080']
metrics_path: '/actuator/prometheus'
# Alert Rule 등록
rule_files:
- "alert.rules.yml"
# AlertManager 연결
alerting:
alertmanagers:
- static_configs:
- targets: ['host.docker.internal:9093']
- host.docker.internal 은 Docker 컨테이너가 호스트의 8080 포트로 접근하도록 설정함
- prometheus.yml, alert.rules.yml은 ./prometheus/ 폴더에 위치시킨다.
3. AlertManager 설정 (alertmanager.yml)
route:
receiver: slack
receivers:
- name: slack
slack_configs:
- api_url: "<SLACK_WEBHOOK_URL>"
channel: 'alert'
send_resolved: true
text: "{{ .CommonAnnotations.summary }} - {{ .CommonAnnotations.description }}"
- Slack Webhook 연동을 통해 알림 전송 설정
4. 알림 조건 설정 (alert.rules.yml)
groups:
- name: give_me_money
rules:
- alert: give_me_money
expr: rate(give_me_money_total[10s]) > 10
for: 10s
labels:
severity: warning
annotations:
summary: "give_me_money"
description: "돈 주세요"
- give_me_money_total이 초당 10 이상이면 경고 발송
5. 테스트 스크립트 (test.sh)
#!/bin/bash
success_count=0
fail_count=0
for i in {1..10000}; do
if (( RANDOM % 2 )); then
curl -s http://localhost:8080/counted > /dev/null
((success_count++))
echo "[${i}/10000] Success: counted endpoint (Total: ${success_count})"
else
curl -s http://localhost:8080/error > /dev/null
((fail_count++))
echo "[${i}/10000] Failure: error endpoint (Total: ${fail_count})"
fi
sleep 1
done
echo "Test complete: ${success_count} successes, ${fail_count} failures."
echo "Checking Prometheus metrics..."
curl -s http://localhost:8080/actuator/prometheus | grep give_me_money_total
6. Docker 컨테이너 실행
# 기존 컨테이너 제거 (필요 시)
docker rm -f prometheus alertmanager
# Prometheus 실행
docker run -d -p 9090:9090 \
-v ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
-v ./prometheus/alert.rules.yml:/etc/prometheus/alert.rules.yml \
--name prometheus \
prom/prometheus:latest
# AlertManager 실행
docker run -d -p 9093:9093 \
-v ./prometheus/alertmanager.yml:/etc/alertmanager/config.yml \
--name alertmanager \
prom/alertmanager:latest
sh test.sh
- 만약 권한 오류가 난다면 ${pwd] 대신 절대 경로를 사용해야 권한 오류가 발생하지 않는다.
7. 확인 포인트
8. Grafana 설정
docker run -d -p 3000:3000 --name grafana grafana/grafana:latest
# localhost:3000
- 데이터 소스 연결
- 대시보드 생성
- Dashboards → Create → Add Visualization
- Prometheus 선택
- 원하는 메트릭 (give_me_money_total 등) 입력해 시각화
9. docker-compose
# Stage 1: Build
FROM azul/zulu-openjdk:17-latest AS build
WORKDIR /app
# 그래들 파일 복사 및 의존성 캐싱
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
RUN chmod +x ./gradlew
# 소스 코드 복사 및 빌드
COPY src src
RUN ./gradlew build -x test
# Stage 2: Runtime
FROM azul/zulu-openjdk:17-latest
WORKDIR /app
# 빌드 스테이지에서 JAR 파일만 복사
COPY --from=build /app/build/libs/*.jar app.jar
EXPOSE 8080
# Spring 프로필을 'prod'로 설정
ENV SPRING_PROFILES_ACTIVE=prod
ENTRYPOINT ["java", "-jar", "app.jar"]
services:
app:
build: . # Dockerfile
ports:
- "8080:8080" # 외부로 Open
networks:
- prom
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus/alert.rules.yml:/etc/prometheus/alert.rules.yml
ports:
- "9090:9090"
networks:
- prom
alertmanager:
image: prom/alertmanager:latest
volumes:
- ./prometheus/alertmanager.yml:/etc/alertmanager/alertmanager.yml
ports:
- "9093:9093"
networks:
- prom
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
networks:
- prom
networks:
prom:
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'spring-boot-app'
static_configs:
# - targets: ['host.docker.internal:8080'] # intellj로 실행 중이거나 별도 네트워크 없이 직접 연결하겠다
- targets: ['app:8080'] # 네트워크에서 컨테이너 이름으로 연결하겠다
metrics_path: '/actuator/prometheus'
# alert manager
rule_files:
- "alert.rules.yml"
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
docker compose up -d
sh test.sh
📌 On-Premise
기업이나 조직이 자체 데이터 센터 또는 서버에 직접 설치하여 운영하는 방식
클라우드(AWS, Azure 등)의 반대 개념
📌 Spring Boot 모니터링 통합 실습: Prometheus, AlertManager, Grafana, Slack 연동
0. 사전 설정: Micrometer 기반 사용자 정의 메트릭 노출
1. application.yml 설정
2. Prometheus 설정 (prometheus.yml)
3. AlertManager 설정 (alertmanager.yml)
4. 알림 조건 설정 (alert.rules.yml)
5. 테스트 스크립트 (test.sh)
6. Docker 컨테이너 실행
7. 확인 포인트
8. Grafana 설정
docker run -d -p 3000:3000 --name grafana grafana/grafana:latest # localhost:30009. docker-compose
📌 On-Premise