-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
📌 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- /actuator/prometheus 엔드포인트를 외부에서 접근 가능하도록 설정
- Prometheus에서 메트릭 수집이 가능해짐
- 테스트 URL: http://localhost:8080/actuator/prometheus
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_total6. 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. 확인 포인트
| 항목 | 주소 또는 명령어 |
|---|---|
| Prometheus UI | http://localhost:9090 |
| AlertManager UI | http://localhost:9093 |
| Spring Boot Actuator | http://localhost:8080/actuator/prometheus |
| 테스트 실행 | sh test.sh |
8. Grafana 설정
docker run -d -p 3000:3000 --name grafana grafana/grafana:latest
# localhost:3000
- 데이터 소스 연결
- Connections → Data Sources → Add Data Source
- Prometheus 선택
- URL: http://host.docker.internal:9090
- 대시보드 생성
- 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"]- docker-compose.yml
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:- prometheus.yml 변경
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']- bash
docker compose up -d
sh test.sh📌 On-Premise
기업이나 조직이 자체 데이터 센터 또는 서버에 직접 설치하여 운영하는 방식
클라우드(AWS, Azure 등)의 반대 개념