Monitoring 실전 가이드
Monitoring의 핵심 개념과 실무 활용
학습 항목
이미지 로딩 중...
Monitoring 트러블슈팅 실전 가이드
프로덕션 환경에서 발생하는 모니터링 이슈를 진단하고 해결하는 실전 가이드입니다. Prometheus, Grafana, ELK 스택을 활용한 트러블슈팅 기법을 다룹니다.
들어가며
이 글에서는 Monitoring 트러블슈팅 실전 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- 헬스체크_엔드포인트_구현
- 메트릭_수집_설정
- 로그_집계_패턴
- 알림_임계값_설정
- 데이터베이스_슬로우쿼리_추적
- 메모리_누수_탐지
- 분산_트레이싱_구현
- 서킷_브레이커_패턴
- 커스텀_대시보드_구성
- 에러_추적_시스템
- 성능_프로파일링
- 장애_복구_자동화
1. 헬스체크_엔드포인트_구현
개요
서비스 상태를 실시간으로 확인할 수 있는 헬스체크 API를 구현합니다. 데이터베이스와 외부 서비스 연결 상태를 포함합니다.
코드 예제
from flask import Flask, jsonify
import psycopg2
app = Flask(__name__)
@app.route('/health')
def health_check():
try:
conn = psycopg2.connect(database="mydb")
conn.close()
return jsonify({"status": "healthy", "db": "connected"}), 200
except:
return jsonify({"status": "unhealthy", "db": "disconnected"}), 503
설명
/health 엔드포인트로 서비스 상태를 확인하며, 데이터베이스 연결 실패 시 503 상태 코드를 반환하여 로드밸런서가 트래픽을 차단할 수 있습니다.
2. 메트릭_수집_설정
개요
Prometheus 클라이언트로 커스텀 메트릭을 수집하고 노출합니다. 요청 수, 응답 시간, 에러율 등을 추적합니다.
코드 예제
from prometheus_client import Counter, Histogram, generate_latest
from flask import Response
request_count = Counter('http_requests_total', 'Total HTTP Requests')
request_duration = Histogram('http_request_duration_seconds', 'HTTP Request Duration')
@app.route('/metrics')
def metrics():
return Response(generate_latest(), mimetype='text/plain')
@request_duration.time()
def process_request():
request_count.inc()
설명
Counter로 요청 횟수를, Histogram으로 응답 시간을 측정하며, /metrics 엔드포인트로 Prometheus가 스크래핑할 수 있도록 노출합니다.
3. 로그_집계_패턴
개요
구조화된 로깅으로 ELK 스택에서 효율적으로 검색 가능한 로그를 생성합니다. JSON 형식으로 컨텍스트 정보를 포함합니다.
코드 예제
import logging
import json
logger = logging.getLogger(__name__)
def log_error(error, user_id, request_id):
log_data = {
"level": "ERROR",
"message": str(error),
"user_id": user_id,
"request_id": request_id,
"timestamp": datetime.now().isoformat()
}
logger.error(json.dumps(log_data))
설명
JSON 형식의 구조화된 로그는 Elasticsearch에서 필드별 검색이 가능하며, request_id로 분산 트레이싱을 구현할 수 있습니다.
4. 알림_임계값_설정
개요
Prometheus AlertManager 규칙으로 SLA 위반 시 자동 알림을 발송합니다. 에러율과 응답 시간 기반 알림을 설정합니다.
코드 예제
# prometheus_rules.yml
groups:
- name: api_alerts
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 2m
annotations:
summary: "Error rate above 5% for 2 minutes"
- alert: SlowResponse
expr: http_request_duration_seconds > 1
annotations:
summary: "Response time exceeds 1 second"
설명
5분간 에러율이 5%를 초과하거나 응답 시간이 1초를 넘으면 알림이 발송되며, for 절로 일시적 스파이크는 무시합니다.
5. 데이터베이스_슬로우쿼리_추적
개요
느린 쿼리를 자동으로 탐지하고 로깅하여 성능 병목을 찾아냅니다. 실행 시간과 쿼리 계획을 기록합니다.
코드 예제
import time
from functools import wraps
def track_query_time(threshold=1.0):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
duration = time.time() - start
if duration > threshold:
logger.warning(f"Slow query: {func.__name__} took {duration:.2f}s")
return result
return wrapper
return decorator
설명
데코레이터로 쿼리 함수를 감싸서 1초 이상 걸리는 쿼리를 자동 탐지하며, 로그를 통해 최적화 대상을 식별할 수 있습니다.
6. 메모리_누수_탐지
개요
메모리 사용량을 모니터링하여 메모리 누수를 조기에 발견합니다. 프로세스별 메모리 증가 추세를 추적합니다.
코드 예제
import psutil
import os
def monitor_memory():
process = psutil.Process(os.getpid())
mem_info = process.memory_info()
mem_mb = mem_info.rss / 1024 / 1024
if mem_mb > 500: # 500MB 초과 시
logger.warning(f"High memory usage: {mem_mb:.2f} MB")
return mem_mb
설명
psutil로 현재 프로세스의 메모리 사용량을 측정하고, 임계값 초과 시 경고를 발생시켜 메모리 누수를 조기에 발견할 수 있습니다.
7. 분산_트레이싱_구현
개요
마이크로서비스 간 요청 흐름을 추적하여 병목 구간을 파악합니다. OpenTelemetry로 트레이스 ID를 전파합니다.
코드 예제
import uuid
from flask import request, g
@app.before_request
def before_request():
trace_id = request.headers.get('X-Trace-ID', str(uuid.uuid4()))
g.trace_id = trace_id
def call_external_service(url):
headers = {'X-Trace-ID': g.trace_id}
response = requests.get(url, headers=headers)
return response.json()
설명
모든 요청에 고유한 trace_id를 부여하고 하위 서비스 호출 시 전파하여, 분산 시스템에서 요청의 전체 경로를 추적할 수 있습니다.
8. 서킷_브레이커_패턴
개요
장애가 발생한 외부 서비스 호출을 자동으로 차단하여 연쇄 장애를 방지합니다. 실패율 기반으로 회로를 개폐합니다.
코드 예제
class CircuitBreaker:
def __init__(self, threshold=5):
self.failure_count = 0
self.threshold = threshold
self.state = 'CLOSED'
def call(self, func):
if self.state == 'OPEN':
raise Exception("Circuit is OPEN")
try:
result = func()
self.failure_count = 0
return result
except:
self.failure_count += 1
if self.failure_count >= self.threshold:
self.state = 'OPEN'
raise
설명
연속 5회 실패 시 회로를 개방하여 추가 요청을 차단하고, 장애 서비스의 복구 시간을 확보하며 시스템 전체의 안정성을 보호합니다.
9. 커스텀_대시보드_구성
개요
Grafana에서 비즈니스 메트릭을 시각화하는 대시보드를 구축합니다. PromQL로 복합 메트릭을 쿼리합니다.
코드 예제
# grafana_dashboard.json (PromQL 쿼리 예시)
{
"expr": "rate(http_requests_total[5m])",
"legendFormat": "{{method}} {{status}}"
}
# Python에서 메트릭 노출
from prometheus_client import Gauge
active_users = Gauge('active_users_total', 'Active Users')
def update_metrics():
active_users.set(get_active_user_count())
설명
rate() 함수로 초당 요청률을 계산하고, Gauge로 동시 접속자 수 같은 스냅샷 메트릭을 노출하여 실시간 비즈니스 지표를 모니터링합니다.
10. 에러_추적_시스템
개요
Sentry와 통합하여 예외 발생 시 스택 트레이스와 컨텍스트를 자동으로 수집합니다. 에러 그룹핑으로 중요도를 파악합니다.
코드 예제
import sentry_sdk
from sentry_sdk import capture_exception
sentry_sdk.init(dsn="your-sentry-dsn")
def risky_operation(user_id):
try:
result = perform_operation()
except Exception as e:
sentry_sdk.set_context("user", {"id": user_id})
capture_exception(e)
raise
설명
예외 발생 시 Sentry가 자동으로 스택 트레이스, 환경 정보, 사용자 컨텍스트를 수집하여 재현 가능한 버그 리포트를 생성합니다.
11. 성능_프로파일링
개요
cProfile로 코드의 병목 지점을 찾아내고 최적화 대상을 식별합니다. 함수별 실행 시간과 호출 횟수를 분석합니다.
코드 예제
import cProfile
import pstats
def profile_function():
profiler = cProfile.Profile()
profiler.enable()
# 프로파일링할 코드
expensive_operation()
profiler.disable()
stats = pstats.Stats(profiler)
stats.sort_stats('cumulative')
stats.print_stats(10)
설명
cumulative 시간 기준으로 정렬하여 가장 많은 시간을 소비하는 상위 10개 함수를 출력하며, 최적화 우선순위를 결정할 수 있습니다.
12. 장애_복구_자동화
개요
특정 조건 충족 시 자동으로 서비스를 재시작하거나 스케일링하여 장애를 자동 복구합니다. Kubernetes liveness probe를 활용합니다.
코드 예제
# kubernetes_deployment.yaml
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
# Python 헬스체크
@app.route('/health')
def health():
if check_critical_resources():
return "OK", 200
return "FAIL", 503
설명
헬스체크가 3번 연속 실패하면 Kubernetes가 자동으로 컨테이너를 재시작하여 일시적 장애에서 자동 복구되며, 운영 부담을 줄입니다.
마치며
이번 글에서는 Monitoring 트러블슈팅 실전 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#Python #Monitoring #Prometheus #Grafana #Troubleshooting