🤖 [STEP 6] 시스템 자동화 및 AI/크립토 자동화 시스템

11. [Monitoring] Prometheus + Grafana로 봇 상태 시각화: "눈에 보이지 않는 시스템은 반드시 무너집니다"

Bobaero Booktech-Lab 2026. 6. 20. 12:05

안녕하세요! 보배로의 북테크랩입니다.

지난 시간, 우리는 REST APIWebSocket의 구조적 차이를 완벽히 이해하고, 초당 수십 번씩 뿜어져 나오는 실시간 틱 데이터를 단 1ms의 지연도 없이 받아들이는 비동기 시세 동기화 엔진을 구축했습니다.

이제 우리의 봇은 뇌(Config)와 보안 격벽(Vault), 그리고 초고속 감각기관(WebSocket)까지 갖춘 완벽한 포식자가 되었습니다. 하지만 이 모든 장치가 서버 내부에서 정상적으로 돌고 있는지, CPU가 비명을 지르고 있지는 않은지, 혹은 메모리 누수(Memory Leak)가 발생해 조용히 다운되기 직전인지 우리가 실시간으로 감시할 수 없다면 어떨까요?

트레이딩 시스템에서 가장 무서운 것은 '에러를 뿜으며 멈추는 봇'이 아니라, '아무런 알림도 없이 조용히 오작동하며 돈을 갉아먹는 봇'입니다. 오늘은 금융권과 글로벌 대기업에서 표준으로 사용하는 모니터링 조합, Prometheus(프로메테우스)와 Grafana(그라파나)를 연동하여 우리의 자동매매 시스템을 완벽하게 시각화하고 계측해 보겠습니다.

1. Prometheus와 Grafana의 역할 분담 : "감시관과 계측판"

프로그램의 상태를 모니터링하기 위해서는 데이터를 '수집'하는 도구와 이를 '보여주는' 도구가 각각 필요합니다.

  • Prometheus (데이터 수집 및 시계열 DB): 우리 파이썬 봇이 뱉어내는 실시간 지표(Metrics)—예를 들면 현재 CPU 사용량, 가용 메모리, 에러 발생 횟수, 실시간 자산 잔고 등을 주기적으로 긁어가서(Scrape) 저장하는 역할을 합니다.
  • Grafana (시각화 대시보드): 프로메테우스가 수집한 차가운 숫자 데이터를 인간이 한눈에 알아볼 수 있도록 아름다운 그래프와 차트, 실시간 경고(Alert) 시스템으로 뿜어주는 화려한 계측판입니다.

이 조합이 완성되면, 우리는 모니터 화면 하나만 켜두고도 "내 봇의 건강 상태"와 "실시간 에러율"을 완벽하게 통제할 수 있게 됩니다.

2. [실습] 파이썬 봇에 Prometheus 메트릭 이식하기

우리 파이썬 봇 내부의 가상 환경(venv)에서 프로메테우스가 데이터를 긁어갈 수 있도록 메트릭을 노출하는 표준 코드를 구현해 보겠습니다.

1단계: Prometheus 클라이언트 라이브러리 설치

가상 환경이 활성화된 상태에서 아래 명령어를 실행합니다.

Bash
 
pip install prometheus_client

2단계: 메트릭 수집 엔진 코드 (monitoring_agent.py) 작성

Python
 
from prometheus_client import start_http_server, Counter, Gauge
import time
import random
import logging

# 💡 프로메테우스의 핵심 메트릭 2가지 정의
# 1. Counter: 누적해서 증가만 하는 지표 (예: 에러 발생 횟수)
ERROR_COUNTER = Counter(
    'bot_error_total', 
    '봇에서 발생한 총 에러 횟수', 
    ['error_type'] # 라벨을 통해 에러 유형별 분리 감시 가능
)

# 2. Gauge: 오르락내리락하는 실시간 지표 (예: 가용 자산, CPU 사용률)
SYSTEM_RESOURCE_GAUGE = Gauge(
    'bot_resource_usage_percent', 
    '봇 시스템 자원 사용률', 
    ['resource_type']
)

WALLET_BALANCE_GAUGE = Gauge(
    'bot_wallet_balance_krw',
    '실시간 봇 자산 잔고 (KRW)'
)

def simulate_trading_bot():
    logging.info("[Monitor] 자동매매 봇 구동 및 메트릭 수집 시작...")
    
    # 실전 예시 자산 설정
    current_balance = 10000000 # 1,000만 원 시작
    
    while True:
        try:
            # 1. 가상의 시스템 리소스 및 자산 변동 시뮬레이션
            simulated_cpu = random.uniform(10.0, 85.0)
            simulated_market_change = random.randint(-50000, 70000)
            current_balance += simulated_market_change
            
            # 2. 프로메테우스 가우지에 실시간 데이터 주입
            SYSTEM_RESOURCE_GAUGE.labels(resource_type='cpu').set(simulated_cpu)
            WALLET_BALANCE_GAUGE.set(current_balance)
            
            # 3. 인위적 에러 발생 시뮬레이션 (API 타임아웃 등)
            if simulated_cpu > 80.0:
                logging.warning("[Warn] CPU 위험 수치 도달! API 지연 발생 가능성 증가.")
                ERROR_COUNTER.labels(error_type='api_timeout').inc() # 카운터 1 증가
                
            time.sleep(5) # 5초 주기로 메트릭 갱신
            
        except Exception as e:
            ERROR_COUNTER.labels(error_type='runtime_error').inc()
            logging.error(f"예상치 못한 루프 에러: {e}")
            time.sleep(1)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s: %(message)s')
    
    # 💡 8000번 포트로 프로메테우스가 데이터를 긁어갈 수 있는 내부 웹서버를 개방합니다.
    # AWS 서울 리전 EC2 보안그룹(Security Group)에서 8000번 포트는 철저히 인바운드 제어를 해야 합니다.
    start_http_server(8000)
    logging.info("[Prometheus] 메트릭 노출 서버가 8000번 포트에서 활성화되었습니다.")
    
    # 봇 구동
    simulate_trading_bot()

📖 실제 장애 사고 사례: "조용한 킬러, 메모리 누수와 계좌의 최후"

과거 한 트레이더가 비동기 웹소켓(10강)을 활용해 초고속 단타 봇을 개발했습니다. 봇은 며칠 동안 아무런 에러 메시지도 없이 완벽하게 수익을 내며 작동하는 것처럼 보였습니다.

하지만 코드 내부에서 수신된 실시간 호가 데이터를 제대로 해제하지 않고 메모리에 계속 누적시키는 메모리 누수(Memory Leak) 버그가 숨어 있었습니다. 봇이 켜진 지 5일째 되던 날 새벽, 서버의 RAM이 99%까지 가득 차자 리눅스 운영체제는 시스템을 보호하기 위해 가장 메모리를 많이 먹는 프로세스를 강제로 죽이는 OOM Killer(Out of Memory Killer)를 발동시켰습니다.

결국 우리 봇은 어떤 에러 로그도 남기지 못하고 그냥 허공으로 증발하듯 멈춰 섰습니다. 하필 그 타이밍에 대규모 시장 폭락이 찾아왔고, 봇이 다운된 상태였기에 손절(Stop-Loss) 로직은 구경조차 못 한 채 포지션이 청산당했습니다.

만약 그라파나 대시보드가 있었다면? 메모리가 우상향하며 차오르는 기괴한 격차 그래프를 진작 발견했을 것이고, 90% 임계치에 도달했을 때 텔레그램 경고 알림을 받아 대참사를 100% 사전에 방어할 수 있었을 것입니다. 모니터링은 투자가 아니라, 내 자산을 지키는 생존 인프라입니다.

🛡️ Prometheus + Grafana 운영 체크리스트

  • [ ] 보안 그룹 격리: 메트릭을 노출하는 8000번 포트 및 프로메테우스 포트(9090), 그라파나 포트(3000)가 외부에 무방비로 열려있지 않고, 내 IP 및 내부 서브넷에서만 접근 가능하도록 제한했는가?
  • [ ] 임계치 알림(Alerting) 설정: Grafana 대시보드에서 CPU > 80%, Memory > 85%, Error Counter 증가율 > 5 일 때 내 텔레그램이나 디스코드로 즉시 경보가 오도록 룰을 세팅했는가?
  • [ ] 라벨링 세분화: 에러 카운터 생성 시 단순히 숫자만 올리지 않고, error_type='network', error_type='order_failed' 처럼 라벨을 정교하게 나누어 추적 가능하게 했는가?
  • [ ] 자산 괴리율 감시: 내 봇이 인지하는 로컬 자산 데이터와 거래소 API가 반환하는 실제 잔고 간의 괴리율(Spread)을 Gauge로 만들어 격차를 상시 감시하고 있는가?

📝 보배로의 통찰: "측정할 수 없다면, 제어할 수 없고, 개선할 수 없다"

현대 금융 공학의 정점은 화려한 예측 알고리즘이 아닙니다. 시스템이 삐걱거리는 순간을 1초 만에 포착해 내는 철저한 계측(Telemetry) 능력에 있습니다. 내 코드가 서버에서 살아 숨 쉬는 모든 궤적을 데이터화하고 그라파나의 시각화 화면으로 완전히 장악하십시오. 숫자가 지표가 되고, 지표가 대시보드가 될 때, 우리의 자동매매 시스템은 단순한 스크립트 쪼가리가 아닌 하나의 견고한 '금융 인프라'로 격상됩니다.

모니터링 시스템을 통해 봇이 죽어가는 신호를 포착하는 방법을 배웠으니, 다음 단계는 실제로 봇이 죽었을 때 인간의 개입 없이 시스템이 스스로 심폐소생술을 실시하는 기술입니다.

다음 시간에는 봇의 생사여부를 실시간으로 체크하고 1초 만에 프로세스를 강제 부팅하는 기술, [12. Heartbeat] 봇 생존 확인 및 프로세스 자동 재시작 시스템에 대해 알아보겠습니다.

보배로의 북테크랩(Booktech-lab) 공학적으로 투자하고, 데이터로 증명하며, 시스템으로 승리합니다.