만들기
Grafana를 활용한 Apache 로그 실시간 통계 대시보드 구축
by googsu.com
2025. 10. 2.
개요
이번 포스트에서는 Docker + ELK 스택에 Grafana를 추가하여 Apache 로그를 기반으로 한 실시간 통계 대시보드를 구축하는 방법을 소개합니다. IP별 접속자 추이, URL별 접속자 추이 등 다양한 시각화를 통해 웹 서버의 트래픽을 효과적으로 모니터링할 수 있습니다.
사전 준비
- Docker & Docker Compose 설치
- ELK 스택 (Elasticsearch + Kibana) 구축 완료
아키텍처 개요
1단계: Grafana 컨테이너 추가
Docker Compose 설정
# elk/docker-compose.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.enabled=false
ports:
- "9200:9200"
networks:
- elk
restart: unless-stopped
kibana:
image: docker.elastic.co/kibana/kibana:8.11.0
container_name: kibana
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
ports:
- "5601:5601"
networks:
- elk
depends_on:
- elasticsearch
restart: unless-stopped
grafana:
image: grafana/grafana:latest
container_name: grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
- GF_USERS_ALLOW_SIGN_UP=false
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
networks:
- elk
depends_on:
- elasticsearch
restart: unless-stopped
networks:
elk:
driver: bridge
external: true
volumes:
elasticsearch_data:
grafana_data:
2단계: Grafana 데이터 소스 설정
Elasticsearch 데이터 소스 구성
# elk/grafana/provisioning/datasources/elasticsearch.yml
apiVersion: 1
datasources:
- name: Elasticsearch
type: elasticsearch
access: proxy
url: http://elasticsearch:9200
database: ""
jsonData:
index: "wordpress-logs-*,php-server-logs-*"
timeField: "@timestamp"
esVersion: "8.0.0"
logMessageField: "message"
logLevelField: "apache.response_code"
editable: true
대시보드 프로비저닝 설정
# elk/grafana/provisioning/dashboards/dashboard.yml
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards
3단계: Apache 로그 대시보드 구성
주요 패널 구성
1. IP별 접속자 일별 추이
{
"title": "IP별 접속자 일별 추이",
"type": "timeseries",
"targets": [
{
"expr": "sum by (apache.client_ip) (count_over_time({job=\"elasticsearch\"} | json | apache.client_ip != \"\" | line_format \"{{.apache.client_ip}}\" [1d]))",
"refId": "A"
}
]
}
2. URL별 접속자 일별 추이
{
"title": "URL별 접속자 일별 추이",
"type": "timeseries",
"targets": [
{
"expr": "sum by (apache.request_path) (count_over_time({job=\"elasticsearch\"} | json | apache.request_path != \"\" | line_format \"{{.apache.request_path}}\" [1d]))",
"refId": "A"
}
]
}
3. 상위 IP 주소 통계
{
"title": "상위 IP 주소",
"type": "stat",
"targets": [
{
"expr": "topk(10, sum by (apache.client_ip) (count_over_time({job=\"elasticsearch\"} | json | apache.client_ip != \"\" | line_format \"{{.apache.client_ip}}\" [1d])))",
"refId": "A"
}
]
}
4. 응답 코드 분포
{
"title": "응답 코드 분포",
"type": "piechart",
"targets": [
{
"expr": "sum by (apache.response_code) (count_over_time({job=\"elasticsearch\"} | json | apache.response_code != \"\" | line_format \"{{.apache.response_code}}\" [1d]))",
"refId": "A"
}
]
}
4단계: 시스템 실행
1. ELK + Grafana 스택 시작
cd elk
docker-compose up -d
2. 서비스 상태 확인
docker ps | grep -E "(elasticsearch|kibana|grafana)"
3. 로그 생성 테스트
# WordPress 접속
curl -s "http://localhost:8081" > /dev/null
# PHP-Server 접속
curl -s "http://localhost:8080" > /dev/null
5단계: Grafana 접속 및 설정