Grafana 대시보드 구성
Grafana는 Prometheus, Loki, InfluxDB 등 다양한 데이터소스의 메트릭과 로그를 시각화하는 오픈소스 분석 플랫폼입니다. 이 챕터에서는 Grafana 설치부터 Nginx와 Tomcat 전용 대시보드 구성, 알림 설정, JSON 프로비저닝, Loki 로그 패널 연동까지 운영 환경에서 즉시 활용할 수 있는 수준으로 다룹니다.
Grafana 설치
Docker로 설치 (권장)
docker run -d \
--name grafana \
-p 3000:3000 \
-e GF_SECURITY_ADMIN_USER=admin \
-e GF_SECURITY_ADMIN_PASSWORD=admin123 \
-v grafana-data:/var/lib/grafana \
grafana/grafana:10.4.2
# 브라우저에서 접근: http://localhost:3000
# 초기 계정: admin / admin123
apt로 설치 (Debian/Ubuntu)
# GPG 키 및 저장소 추가
sudo apt-get install -y apt-transport-https software-properties-common wget
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | \
sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install -y grafana
# 서비스 시작
sudo systemctl enable --now grafana-server
# 상태 확인
sudo systemctl status grafana-server
# 웹 UI: http://localhost:3000
기본 설정 확인
# /etc/grafana/grafana.ini (주요 항목만)
[server]
http_port = 3000
domain = your-domain.com
root_url = https://%(domain)s/
[security]
admin_user = admin
admin_password = your-secure-password
[users]
allow_sign_up = false
default_theme = dark
[auth.anonymous]
enabled = false
sudo systemctl restart grafana-server
Prometheus 데이터소스 연결
웹 UI에서 수동 연결
- 좌측 메뉴 → Connections→ ** Data sources**→ ** Add data source**
- Prometheus 선택
- 설정:
- Name:
Prometheus - URL:
http://prometheus:9090(Docker Compose) 또는http://localhost:9090 - Scrape interval:
15s
- Name:
- Save & test 클릭 → "Successfully queried the Prometheus API." 확인
API로 데이터소스 등록 (자동화)
curl -X POST http://admin:admin123@localhost:3000/api/datasources \
-H "Content-Type: application/json" \
-d '{
"name": "Prometheus",
"type": "prometheus",
"url": "http://prometheus:9090",
"access": "proxy",
"isDefault": true,
"jsonData": {
"httpMethod": "POST",
"scrapeInterval": "15s"
}
}'
Nginx 대시보드 구성
공개 대시보드 임포트 (ID: 12559)
Grafana Labs에서 제공하는 공개 Nginx 대시보드를 임포트하는 가장 빠른 방법입니다:
- 좌측 메뉴 → Dashboards→ ** Import**
- Dashboard ID:
12559입력 후 ** Load**클릭 - 데이터소스로
Prometheus선택 후 Import
직접 패널 구성
Nginx 대시보드에서 핵심적으로 필요한 패널을 직접 만드는 방법입니다.
패널 1: 초당 요청 수 (RPS)
패널 유형: Time series
쿼리:
rate(nginx_http_requests_total[5m])
패널 제목: Nginx RPS
단위: reqps (requests/sec)
패널 2: 응답 시간 (p95)
패널 유형: Time series
쿼리:
histogram_quantile(0.95, rate(nginx_request_duration_seconds_bucket[5m]))
패널 제목: Response Time (p95)
단위: seconds
임계선: 1.0s (warning), 2.0s (critical)
패널 3: HTTP 상태 코드별 비율
패널 유형: Pie chart
쿼리:
sum by (status) (rate(nginx_http_requests_total[5m]))
패널 제목: HTTP Status Distribution
패널 4: 에러율 (5xx)
패널 유형: Stat
쿼리:
sum(rate(nginx_http_requests_total{status=~"5.."}[5m]))
/
sum(rate(nginx_http_requests_total[5m])) * 100
패널 제목: 5xx Error Rate (%)
임계값: 1% = yellow, 5% = red
패널 5: 활성 연결 수
패널 유형: Gauge
쿼리:
nginx_connections_active
패널 제목: Active Connections
최대값: 1000
임계값: 500 = yellow, 800 = red
패널 6: 연결 상태 분포 (Reading/Writing/Waiting)
패널 유형: Bar chart
쿼리들:
nginx_connections_reading (Alias: Reading)
nginx_connections_writing (Alias: Writing)
nginx_connections_waiting (Alias: Waiting)
패널 제목: Connection State
Tomcat 대시보드 구성
공개 대시보드 임포트 (ID: 4701)
JVM 모니터링을 위한 공개 대시보드:
- 좌측 메뉴 → Dashboards→ ** Import**
- Dashboard ID:
4701입력 후 ** Load** - 데이터소스로
Prometheus선택 후 Import
Tomcat 전용 패널 구성
패널 1: JVM 힙 메모리 사용량
패널 유형: Time series
쿼리:
jvm_memory_heap_used_bytes (Alias: Used)
jvm_memory_heap_max_bytes (Alias: Max)
패널 제목: JVM Heap Memory
단위: bytes (auto)
패널 2: JVM 힙 사용률 (%)
패널 유형: Gauge
쿼리:
jvm_memory_heap_used_bytes / jvm_memory_heap_max_bytes * 100
패널 제목: JVM Heap Usage (%)
최대값: 100
임계값: 70 = yellow, 90 = red
패널 3: Tomcat 스레드 풀 현황
패널 유형: Time series
쿼리:
tomcat_threadpool_currentthreadcount{connector="http-nio-8080"} (Alias: Current)
tomcat_threadpool_currentthreadsbusy{connector="http-nio-8080"} (Alias: Busy)
tomcat_threadpool_maxthreads{connector="http-nio-8080"} (Alias: Max)
패널 제목: Thread Pool (http-nio-8080)
패널 4: 요청 처리량 (RPS)
패널 유형: Time series
쿼리:
rate(tomcat_requestcount_total{connector="http-nio-8080"}[5m])
패널 제목: Request Rate (RPS)
단위: reqps
패널 5: GC 실행 빈도
패널 유형: Time series
쿼리:
rate(jvm_gc_CollectionCount_total[5m])
패널 제목: GC Collection Rate
패널 6: GC 소요 시간
패널 유형: Time series
쿼리:
rate(jvm_gc_CollectionTime_total[5m])
패널 제목: GC Collection Time (ms/s)
알림(Alerting) 설정
Contact Point 설정 — Slack
- 좌측 메뉴 → Alerting→ ** Contact points**→ ** Add contact point**
- 이름:
Slack-Ops - Slack 선택
- Webhook URL: Slack 인입 웹훅 URL 입력
- Optional Slack settings:
- Channel:
#alerts - Username:
Grafana Alert - Icon emoji:
:bell:
- Channel:
- Test 버튼으로 메시지 확인 후 Save contact point
Contact Point 설정 — 이메일
# /etc/grafana/grafana.ini 에 SMTP 설정 추가
[smtp]
enabled = true
host = smtp.gmail.com:587
user = your-email@gmail.com
password = your-app-password
skip_verify = false
from_address = grafana@example.com
from_name = Grafana
sudo systemctl restart grafana-server
이메일 Contact Point 생성:
- Alerting→ ** Contact points**→ ** Add contact point**
- Email 선택
- Addresses:
ops-team@example.com - Save contact point
알림 룰 생성
- Alerting→ ** Alert rules**→ ** New alert rule**
- 쿼리 작성:
# Nginx 5xx 에러율 5% 초과 알림
sum(rate(nginx_http_requests_total{status=~"5.."}[5m]))
/
sum(rate(nginx_http_requests_total[5m])) * 100 - Conditions 설정:
- Condition:
IS ABOVE 5(5% 초과 시 알림) - For:
2m(2분 지속 시 발화)
- Condition:
- Labels:
severity=critical - Notification policy 탭에서 Contact Point 연결
- Save rule
Notification Policy 설정
- Alerting→ ** Notification policies**
- 기본 정책 수정 또는 새 정책 추가
- Matchers:
severity=critical→ Contact Point:Slack-Ops - Repeat interval:
12h
대시보드 JSON 프로비저닝 (자동 로드)
Grafana 시작 시 대시보드를 자동으로 로드하는 프로비저닝 기능입니다. CI/CD 파이프라인에서 대시보드를 코드로 관리할 때 유용합니다.
프로비저닝 설정
# /etc/grafana/provisioning/dashboards/default.yml
# 또는 grafana/provisioning/dashboards/default.yml (Docker)
apiVersion: 1
providers:
- name: 'default'
orgId: 1
type: file
disableDeletion: false
updateIntervalSeconds: 30 # 30초마다 변경 감지
allowUiUpdates: true
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: true
데이터소스 프로비저닝
# /etc/grafana/provisioning/datasources/prometheus.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
jsonData:
httpMethod: POST
scrapeInterval: "15s"
version: 1
editable: true
대시보드 JSON 내보내기 및 저장
UI에서 만든 대시보드를 JSON으로 내보내는 방법:
- 대시보드 우측 상단 Share 아이콘 → Export
- Export for sharing externally 토글 켜기
- Save to file 클릭 →
nginx-dashboard.json파일 다운로드 - 파일을
/var/lib/grafana/dashboards/또는 Docker 볼륨 마운트 경로에 복사
Docker Compose에서 자동 적용:
# docker-compose.yml
grafana:
image: grafana/grafana:10.4.2
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning:ro
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
Grafana + Loki 연동 (로그 패널)
Loki는 Prometheus와 동일한 레이블 모델을 사용하는 로그 집계 시스템입니다. Grafana와 통합하면 메트릭과 로그를 같은 대시보드에서 분석할 수 있습니다.
Loki + Promtail Docker Compose 추가
# docker-compose.yml에 추가
loki:
image: grafana/loki:3.0.0
container_name: loki
ports:
- "3100:3100"
volumes:
- ./loki/loki-config.yml:/etc/loki/loki-config.yml:ro
- loki-data:/loki
command: -config.file=/etc/loki/loki-config.yml
networks:
- monitoring
promtail:
image: grafana/promtail:3.0.0
container_name: promtail
volumes:
- /var/log/nginx:/var/log/nginx:ro
- ./promtail/promtail-config.yml:/etc/promtail/config.yml:ro
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki
networks:
- monitoring
# loki/loki-config.yml
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
chunk_idle_period: 5m
chunk_retain_period: 30s
schema_config:
configs:
- from: 2024-01-01
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/cache
filesystem:
directory: /loki/chunks
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h
# promtail/promtail-config.yml
server:
http_listen_port: 9080
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: nginx
static_configs:
- targets:
- localhost
labels:
job: nginx
__path__: /var/log/nginx/access.log
pipeline_stages:
- regex:
expression: '^(?P<remote_addr>\S+) - (?P<remote_user>\S+) \[(?P<time_local>[^\]]+)\] "(?P<request>[^"]+)" (?P<status>\d+) (?P<body_bytes_sent>\d+)'
- labels:
status:
remote_addr:
Loki 데이터소스 등록
curl -X POST http://admin:admin123@localhost:3000/api/datasources \
-H "Content-Type: application/json" \
-d '{
"name": "Loki",
"type": "loki",
"url": "http://loki:3100",
"access": "proxy"
}'
Grafana 로그 패널 구성
대시보드에 Logs 패널 추가:
- 대시보드 편집 → Add panel→ 패널 유형: ** Logs**
- 데이터소스:
Loki - 쿼리:
# Nginx 5xx 에러 로그
{job="nginx"} |= "\" 5" | regexp `(?P<status>\d{3})` | status =~ "5.."
# 특정 IP 요청 로그
{job="nginx"} |= "203.0.113.5"
# 느린 요청 (응답 시간 포함 JSON 포맷)
{job="nginx"} | json | request_time > 1.0 - 패널 저장
고수 팁
대시보드 폴더 구조: 프로비저닝 경로에서 foldersFromFilesStructure: true를 설정하면 디렉토리 구조가 Grafana의 폴더 구조로 자동 매핑됩니다.
grafana/dashboards/
├── nginx/
│ ├── nginx-overview.json
│ └── nginx-errors.json
└── tomcat/
├── jvm-metrics.json
└── tomcat-requests.json
변수를 활용한 동적 대시보드: 여러 서버를 하나의 대시보드에서 관리할 때는 템플릿 변수를 활용합니다.
- 대시보드 설정 → Variables→ ** Add variable**
- Type:
Query - 쿼리:
label_values(nginx_connections_active, instance) - 패널 쿼리에
$instance변수 적용:nginx_connections_active{instance="$instance"}
Explore 기능: 좌측 메뉴의 ** Explore**에서 Prometheus와 Loki 쿼리를 즉석에서 실행하고 메트릭-로그를 함께 확인할 수 있어 장애 분석 시 매우 유용합니다.