Project/Boilerplate

Prometheus + Grafana ์—ฐ๋™

์กฐ์šฉ์šฐ 2025. 4. 12. 00:50

๐ŸŽฏ ์ตœ์ข… ๋ชฉํ‘œ: ์ด๋ ‡๊ฒŒ ๋œ๋‹ค!

Spring Boot์—์„œ ์„œ๋ฒ„ ์ƒํƒœ ์ •๋ณด๋ฅผ ์ˆซ์ž๋กœ ๋ฝ‘์•„๋‚ด๊ณ 
→ Prometheus๊ฐ€ ๊ทธ๊ฑธ ์ˆ˜์ง‘ํ•˜๊ณ 
→ Grafana๊ฐ€ ๋ณด๊ธฐ ์ข‹๊ฒŒ ๊ทธ๋ž˜ํ”„๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.


โœ… Step 1: Spring Boot Actuator๊ฐ€ "์„œ๋ฒ„ ์ƒํƒœ ๋ฐ์ดํ„ฐ"๋ฅผ ๋ฝ‘๋Š”๋‹ค

์˜ˆ: ์ด๋Ÿฐ ๋ฐ์ดํ„ฐ๋“ค์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋จ

 

ํ•ญ๋ชฉ ์„ค๋ช…
jvm.memory.used JVM ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰
http.server.requests HTTP ์š”์ฒญ ์ˆ˜, ์‘๋‹ต ์‹œ๊ฐ„
system.cpu.usage CPU ์‚ฌ์šฉ๋ฅ 
process.uptime ์„œ๋ฒ„ ์‹คํ–‰ ์‹œ๊ฐ„
logback.events ๋กœ๊ทธ ๋ฐœ์ƒ ์ˆ˜

๐Ÿ‘‰ ์ด ๋ฐ์ดํ„ฐ๋Š” /actuator/prometheus๋ผ๋Š” URL์— ์ˆซ์ž + ์„ค๋ช… ํ˜•์‹์œผ๋กœ ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค:

# HELP jvm_memory_used_bytes The amount of used memory
jvm_memory_used_bytes{area="heap",id="G1 Eden Space",} 2.515968E7

โœ… Step 2: Prometheus๊ฐ€ /actuator/prometheus์— 15์ดˆ๋งˆ๋‹ค ์ ‘๊ทผํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘

Prometheus๋Š” "์•ผ, ๋„ˆ ์ง€๊ธˆ ์ƒํƒœ ์–ด๋•Œ?" ํ•˜๊ณ  15์ดˆ๋งˆ๋‹ค ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'spring-boot-app'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['host.docker.internal:8080']

๐Ÿ’ก ์—ฌ๊ธฐ์„œ host.docker.internal์€ ๋กœ์ปฌ์—์„œ ๋„์šด Spring ์„œ๋ฒ„๋ฅผ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์•ˆ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ‚ค์›Œ๋“œ์ž…๋‹ˆ๋‹ค (๋งฅ/์œˆ๋„์šฐ ๊ธฐ์ค€)

 

๐Ÿ” ์ด ๋ธ”๋ก์˜ ์˜๋ฏธ:

์„ค์ • ํ•ญ๋ชฉ์„ค๋ช…
job_name: 'spring-boot-app' ์ด ์„ค์ • ๋ธ”๋ก์„ Prometheus ๋‚ด๋ถ€์—์„œ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ ์ด๋ฆ„ (๋Œ€์‹œ๋ณด๋“œ ๋“ฑ์—์„œ ์ด ์ด๋ฆ„์œผ๋กœ ๊ทธ๋ฃนํ™”๋จ)
metrics_path: '/actuator/prometheus' ๋ฉ”ํŠธ๋ฆญ์„ ์ˆ˜์ง‘ํ•  HTTP ๊ฒฝ๋กœ (Spring Boot๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ด ๊ฒฝ๋กœ์—์„œ ๋…ธ์ถœํ•จ)
targets: ['host.docker.internal:8080'] ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•  ์‹ค์ œ ๋Œ€์ƒ ์„œ๋ฒ„ (์—ฌ๊ธฐ์„œ๋Š” ๋กœ์ปฌ์—์„œ 8080์œผ๋กœ ์‹คํ–‰ ์ค‘์ธ Spring Boot ์„œ๋ฒ„)

 


โœ… Step 3: Grafana๊ฐ€ Prometheus์—์„œ ์ˆ˜์ง‘๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”

Grafana๋Š” ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜์ง€ ์•Š๊ณ ,
โžก Prometheus์— ์Œ“์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ์ž…๋‹ˆ๋‹ค.

  • ์˜ˆ: CPU ์‚ฌ์šฉ๋ฅ  → ์„  ๊ทธ๋ž˜ํ”„
  • ์˜ˆ: API ์‘๋‹ต ์†๋„ → ์‹œ๊ฐ„๋Œ€๋ณ„ ๊บพ์€์„  ๊ทธ๋ž˜ํ”„
  • ์˜ˆ: ์—๋Ÿฌ ์‘๋‹ต ๋น„์œจ → ๋„๋„› ์ฐจํŠธ

๐Ÿ‘‡ ์ด๋Ÿฐ ์‹์œผ๋กœ ๋ณด์—ฌ์ง‘๋‹ˆ๋‹ค

์‹œ๊ฐ„ → 15์ดˆ ๊ฐ„๊ฒฉ ๊ฐ’ → CPU ์‚ฌ์šฉ๋Ÿ‰, ์š”์ฒญ ์ˆ˜, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋“ฑ

โœ… Step 4: Grafana์—์„œ Dashboard ๋งŒ๋“ค๊ธฐ

  1. http://localhost:3001 ์ ‘์†
  2. ๋กœ๊ทธ์ธ (๊ธฐ๋ณธ: admin / admin)
  3. ์ขŒ์ธก ๋ฉ”๋‰ด → โš™๏ธ Data Sources → Prometheus ์ถ”๊ฐ€
  4. ์ขŒ์ธก ๋ฉ”๋‰ด → ๐Ÿ“Š Dashboards → Import
  5. Dashboard ID: 4701 (Micrometer + Spring Boot ๋Œ€์‹œ๋ณด๋“œ)
  6. ํ™•์ธํ•˜๋ฉด ์ž๋™์œผ๋กœ ๊ทธ๋ž˜ํ”„๋“ค์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค!

โœจ ์ •๋ฆฌ ์ˆœ์„œ

๋‹จ๊ณ„ ์„ค๋ช…
1๏ธโƒฃ Spring Boot์— actuator, micrometer ์ถ”๊ฐ€ → /actuator/prometheus์—์„œ ์ƒํƒœ ๊ณต๊ฐœ
2๏ธโƒฃ Prometheus๊ฐ€ ์ด URL์„ ์ •๊ธฐ์ ์œผ๋กœ ๋ฐฉ๋ฌธํ•ด์„œ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘
3๏ธโƒฃ Grafana๊ฐ€ Prometheus์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ด
4๏ธโƒฃ Grafana ๋Œ€์‹œ๋ณด๋“œ์—์„œ ๊ทธ๋ž˜ํ”„๋กœ ์‹œ๊ฐํ™”๋จ

๐Ÿ“Œ ์‹ค์ œ ์šด์˜์—์„œ ์ด๋Ÿฐ ๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”

  • ์–ด๋А API๊ฐ€ ์ œ์ผ ๋А๋ฆฐ์ง€
  • 5xx ์—๋Ÿฌ๊ฐ€ ๋งŽ์ด ๋ฐœ์ƒํ•œ API๋Š” ๋ฌด์—‡์ธ์ง€
  • ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์žˆ๋Š”์ง€
  • ์„œ๋ฒ„๊ฐ€ ๋‹ค์šด๋˜๊ธฐ ์ „ ์ด์ƒ์ง•ํ›„๋Š” ๋ฌด์—‡์ด์—ˆ๋Š”์ง€

๐Ÿ“ฆ 1๋‹จ๊ณ„: Spring Boot ์„ค์ •

โ‘  ์˜์กด์„ฑ ์ถ”๊ฐ€ (build.gradle)

// APM (Monitoring)
implementation 'org.springframework.boot:spring-boot-starter-actuator'
runtimeOnly 'io.micrometer:micrometer-registry-prometheus'

โ‘ก application.properties ์„ค์ •

# APM
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true

๐Ÿ‘‰ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด http://localhost:8080/actuator/prometheus์—์„œ ๋ฉ”ํŠธ๋ฆญ์ด ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

 

Spring Security์—๋„ ์ถ”๊ฐ€

http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/actuator/**").permitAll() // ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šค

๐Ÿ“ฆ 2๋‹จ๊ณ„: Prometheus + Grafana Docker๋กœ ์‹คํ–‰

๐Ÿ“ docker-compose.yml

version: '3'

services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    ports:
      - "3001:3000"  # 3000๋ฒˆ ํฌํŠธ๋Š” Next.js๊ฐ€ ์“ฐ๊ณ  ์žˆ์œผ๋ฏ€๋กœ 3001๋กœ ๋ณ€๊ฒฝ
    volumes:
      - grafana-storage:/var/lib/grafana

volumes:
  grafana-storage:

๐Ÿ“„ 3๋‹จ๊ณ„: Prometheus ์„ค์ • ํŒŒ์ผ

๐Ÿ“ prometheus/prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'spring-boot-app'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['host.docker.internal:8080']

๐Ÿ“Œ host.docker.internal์€ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋กœ์ปฌ ํ˜ธ์ŠคํŠธ(์œˆ๋„์šฐ/๋งฅ ๊ธฐ์ค€)๋ฅผ ๋ฐ”๋ผ๋ณผ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๋ฆฌ๋ˆ…์Šค๋Š” ๋Œ€์‹  172.17.0.1 ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ network_mode: host ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿš€ 4๋‹จ๊ณ„: ์‹คํ–‰

docker-compose up -d

๐Ÿ“Š 5๋‹จ๊ณ„: Grafana ๋Œ€์‹œ๋ณด๋“œ ๊ตฌ์„ฑ

  1. Grafana ์ ‘์† (ID: admin / PW: admin)
  2. ์ขŒ์ธก "โš™๏ธ ์„ค์ • → Data Sources"
    • Prometheus ์„ ํƒ
    • URL: http://prometheus:9090
  3. "Import Dashboard"
    • ํ…œํ”Œ๋ฆฟ ID: 4701 (Spring Boot with Micrometer)
    • โœ”๏ธ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž๋™์œผ๋กœ ๋“ค์–ด์˜ค๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค