Grafana + Loki 실습 치트시트
📋 빠른 참조
환경 정보
Grafana: http://192.168.1.12
계정: admin / admin
Loki URL (Grafana 내부): http://loki.logging.svc.cluster.local:3100
테스트 네임스페이스: demo-app
- log-generator (2 pods)
- web-api (1 pod)
🔍 LogQL 쿼리 실습 (복사해서 사용하세요!)
기초 쿼리
1. 모든 로그 조회
{namespace=~".+"}2. demo-app 네임스페이스 로그만
{namespace="demo-app"}3. log-generator Pod 로그만
{namespace="demo-app", pod=~"log-generator.*"}4. 특정 컨테이너 로그
{namespace="demo-app", container="logger"}필터링 쿼리
5. ERROR 로그만 필터링
{namespace="demo-app"} |= "ERROR"6. ERROR 또는 WARN 로그
{namespace="demo-app"} |~ "ERROR|WARN"7. INFO 로그 제외
{namespace="demo-app"} != "INFO"8. 대소문자 구분 없이 error 검색
{namespace="demo-app"} |~ "(?i)error"집계 쿼리 (메트릭 생성)
9. 초당 로그 발생률
rate({namespace="demo-app"}[1m])10. Pod별 로그 발생률
sum(rate({namespace="demo-app"}[1m])) by (pod)11. 5분간 ERROR 로그 개수
sum(count_over_time({namespace="demo-app"} |= "ERROR" [5m]))12. Pod별 ERROR 로그 비율
sum(rate({namespace="demo-app"} |= "ERROR" [5m])) by (pod)13. 상위 10개 로그 발생 Pod
topk(10, sum(rate({namespace=~".+"}[5m])) by (pod))고급 쿼리 (파싱 및 추출)
14. 로그 라인 파싱 (패턴 매칭)
{namespace="demo-app"}
| pattern `<_> <_> <level>: <message>`
| level = "ERROR"15. Regex로 user_id 추출
{namespace="demo-app"}
| regexp "user_id=(?P<user_id>\\d+)"16. 네임스페이스별 로그 볼륨 (바이트)
sum(bytes_over_time({namespace=~".+"}[5m])) by (namespace)📊 Grafana Explore 실습 가이드
실습 1: 기본 로그 조회
- Grafana → Explore (🧭 아이콘)
- Data Source: Loki 선택
- 쿼리 입력:
{namespace="demo-app"} - Run Query 클릭
- 시간 범위 조정: Last 15 minutes → Last 5 minutes
- Live 모드 활성화: 우측 상단 “Live” 버튼
실습 2: 로그 레벨 필터링
- ERROR 로그만 조회:
{namespace="demo-app"} |= "ERROR" - Show logs 버튼 클릭 (Logs 시각화 확인)
- 로그 라인 클릭 → 상세 정보 확인
- Filter for value → 추가 필터 적용
실습 3: 메트릭 시각화
- 쿼리 입력:
sum(rate({namespace="demo-app"}[1m])) by (pod) - 시각화 변경: Logs → Time series
- 그래프에서 Pod별 로그 발생 추세 확인
- Legend 클릭 → 특정 Pod만 표시
실습 4: 에러율 모니터링
- Split 버튼 클릭 (쿼리 2개 비교)
- 왼쪽 쿼리:
sum(rate({namespace="demo-app"}[1m])) - 오른쪽 쿼리:
sum(rate({namespace="demo-app"} |= "ERROR" [1m])) - 두 그래프 비교하여 에러율 파악
📈 대시보드 생성 실습
대시보드 1: 실시간 로그 모니터링
- Create → Dashboard → Add new panel
- Data Source: Loki
Panel 1: 실시간 로그 스트림
Title: Demo App Logs
Query: {namespace="demo-app"}
Visualization: Logs
Options:
- Show time: ✅
- Wrap lines: ✅
- Dedupe: None
Panel 2: 로그 발생률 (시계열)
Title: Log Rate by Pod
Query: sum(rate({namespace="demo-app"}[1m])) by (pod)
Visualization: Time series
Legend: {{pod}}
Panel 3: ERROR 로그 카운트
Title: Error Count (5min)
Query: sum(count_over_time({namespace="demo-app"} |= "ERROR" [5m]))
Visualization: Stat
Color mode: Value
Graph mode: None
Panel 4: 로그 레벨 분포
Title: Log Level Distribution
Query:
# TODO(human) - 여기에 로그 레벨별 카운트 쿼리 작성
Visualization: Pie chart
- Save Dashboard (💾 아이콘)
- Name: “Demo App Monitoring”
- Folder: General
대시보드 2: 변수(Variables) 활용
- Dashboard Settings (⚙️) → Variables → Add variable
- 변수 설정:
Name: namespace Type: Query Data source: Loki Query: label_values(namespace) - Save
- 패널 쿼리 수정:
{namespace="$namespace"} - 대시보드 상단에서 네임스페이스 선택 가능!
🧪 추가 실습 과제
과제 1: 커스텀 로그 생성
# VM에서 실행
vagrant ssh cp-k8s-1.30.4
# 커스텀 로그 생성 Pod
kubectl run custom-logger --image=busybox --restart=Never -- sh -c '
while true; do
echo "$(date) - Custom log: Transaction ID $(($RANDOM % 10000))";
sleep 1;
done'
# Grafana에서 확인
{pod="custom-logger"}과제 2: 에러 시뮬레이션
# 집중적인 에러 로그 생성
kubectl run error-bomb --image=busybox --restart=Never -- sh -c '
for i in $(seq 1 100); do
echo "CRITICAL ERROR: System failure at component-$((i % 5))";
sleep 0.5;
done'
# Grafana 쿼리
{pod="error-bomb"} |= "CRITICAL"
count_over_time({pod="error-bomb"} |= "CRITICAL" [1m])과제 3: 멀티 Pod 로그 집계
# 3개의 앱 배포
for i in {1..3}; do
kubectl run app-$i --image=busybox --restart=Never -- sh -c "
while true; do
echo 'App-$i: Processing order #$((RANDOM % 1000))';
sleep 2;
done"
done
# 전체 조회
{pod=~"app-.*"}
# 집계
sum(rate({pod=~"app-.*"}[1m])) by (pod)🎯 실전 시나리오
시나리오 1: 장애 탐지
상황: 특정 시간대에 ERROR가 급증했다는 알림 수신
해결 단계:
- Explore에서 시간 범위를 해당 시간대로 설정
- 쿼리:
{namespace="demo-app"} |= "ERROR" - 에러 메시지 패턴 분석
- Pod별 에러 분포 확인:
sum(count_over_time({namespace="demo-app"} |= "ERROR" [5m])) by (pod)
시나리오 2: 성능 분석
상황: API 응답 시간이 느리다는 보고
해결 단계:
- 응답 시간 관련 로그 검색:
{namespace="demo-app"} |~ "response time|timeout" - 느린 요청 필터링:
{namespace="demo-app"} |~ "response time: [5-9]\\d{2}ms|response time: \\d{4,}ms"
시나리오 3: 보안 이벤트 추적
상황: 인증 실패 로그 모니터링 필요
해결 단계:
- 인증 관련 로그:
{namespace=~".+"} |~ "(?i)auth|login|unauthorized|forbidden" - 실패 횟수 카운트:
sum(count_over_time({namespace=~".+"} |~ "(?i)failed|unauthorized" [5m])) by (namespace)
🛠️ kubectl 명령어 치트시트
Pod 관리
# 모든 Pod 확인
kubectl get pods -A
# demo-app Pod 확인
kubectl get pods -n demo-app
# 특정 Pod 로그 보기
kubectl logs -n demo-app <pod-name>
# 모든 log-generator Pod 로그
kubectl logs -n demo-app -l app=log-generator
# Pod 삭제
kubectl delete pod <pod-name> -n demo-appLoki/Promtail 관리
# Loki 상태 확인
kubectl get pods -n logging
# Loki 로그 확인
kubectl logs -n logging -l app=loki
# Promtail 로그 확인 (특정 노드)
kubectl logs -n logging <promtail-pod-name>
# Loki API 직접 호출
kubectl exec -n logging -it deploy/loki -- wget -O- http://localhost:3100/ready
kubectl exec -n logging -it deploy/loki -- wget -O- http://localhost:3100/metrics디버깅
# Loki 서비스 확인
kubectl get svc -n logging loki
# DNS 확인
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup loki.logging.svc.cluster.local
# Loki 연결 테스트
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- curl http://loki.logging.svc.cluster.local:3100/ready📚 LogQL 문법 요약
Stream Selector (로그 스트림 선택)
{label="value"} # 정확히 일치
{label=~"regex"} # 정규표현식 일치
{label!="value"} # 일치하지 않음
{label!~"regex"} # 정규표현식 불일치
{label1="value1", label2="value2"} # AND 조건Line Filter (로그 라인 필터)
|= "string" # 포함
!= "string" # 미포함
|~ "regex" # 정규표현식 일치
!~ "regex" # 정규표현식 불일치Parser (로그 파싱)
| json # JSON 파싱
| logfmt # logfmt 파싱
| pattern `<pattern>` # 패턴 매칭
| regexp `regex` # 정규표현식 파싱Aggregation (집계)
rate({label="value"}[1m]) # 변화율
count_over_time({label="value"}[5m]) # 개수
bytes_over_time({label="value"}[5m]) # 바이트 합계
sum(rate({label="value"}[1m])) by (label) # 그룹별 합계
avg(rate({label="value"}[1m])) by (label) # 그룹별 평균
max(rate({label="value"}[1m])) by (label) # 그룹별 최대값
topk(10, sum(...) by (label)) # 상위 10개✅ 학습 체크리스트
기초
- Grafana 접속 및 Loki 데이터소스 연결
- Explore에서 기본 로그 조회
- 시간 범위 조정 및 Live 모드 사용
- 로그 라인 필터링 (|=, |~)
- 네임스페이스별 로그 조회
중급
- LogQL 메트릭 쿼리 작성 (rate, count_over_time)
- Pod별 로그 집계
- 대시보드 생성 (최소 3개 패널)
- 시각화 타입 변경 (Logs, Time series, Stat)
- 테스트 로그 생성 및 확인
고급
- 변수(Variables)를 사용한 동적 대시보드
- 복잡한 정규표현식 필터링
- 로그 파싱 및 레이블 추출
- 멀티 쿼리 대시보드 구성
- 알림 설정 (선택)
🚀 다음 단계
- Alert 설정: Grafana에서 로그 기반 알림 구성
- Prometheus 통합: 메트릭 + 로그 통합 대시보드
- Tempo 추가: 분산 트레이싱 연동
- S3 스토리지: Loki 장기 보관 설정
- Helm 차트: 프로덕션급 Loki 스택 배포
작성일: 2025-12-17 환경: Kubernetes 1.30.4, Loki 2.9.3, Grafana 10.x