Grafana 대시보드
quant-ai 스택은 운영을 위한 5개의 Grafana 대시보드와 4개의 unified
alerting 규칙을 코드로 관리합니다 (infra/grafana/). 모든 대시보드는
컨테이너 시작 시 자동 프로비저닝되며, UI에서의 임시 편집은 재시작 시
사라집니다 — 영구 변경은 항상 JSON을 수정하세요.
본 페이지는 기존
docs/operations/grafana_setup.md를 흡수해 운영자 시점으로 재구성한 단일 출처입니다.
1. 접속
| 환경 | URL | 기본 계정 |
|---|---|---|
| 로컬 | http://localhost:3000 | admin / admin |
| Azure VM | http://<vm-ip>:3000 또는 reverse proxy 뒤 | GF_SECURITY_ADMIN_* |
대시보드는 사용자별 PnL과 LLM 비용을 노출하므로 admin 전용 으로 설계되었습니다. read-only viewer를 만들기 전에는 디자인 리뷰가 필요합니다.
로컬에서 Grafana만 띄우려면:
docker compose up -d grafana
다음 디렉토리가 자동 마운트됩니다.
config/grafana/provisioning/— 레거시 BTC 단일 대시보드 (호환)infra/grafana/provisioning/— 멀티자산 / Ops 대시보드 + alertinginfra/grafana/dashboards/*.json— 컨테이너 내부/var/lib/grafana/dashboards/multi-asset/에 매핑
2. 5종 대시보드
모두 quant-ai (Ops) 폴더에 위치합니다.
| 대시보드 | UID | 새로고침 | 기본 범위 |
|---|---|---|---|
| Multi-Asset Overview | quantai-multi-asset-overview | 1m | 24시간 |
| LLM Cost Tracking | quantai-llm-cost | 1m | 7일 |
| Broker Health | quantai-broker-health | 30s | 6시간 |
| Daily Loss Monitor | quantai-daily-loss | 30s | 오늘 (UTC) |
| Worker Queue | quantai-worker-queue | 30s | 6시간 |
어느 대시보드를 언제 보나
- 일일 스탠드업 → Multi-Asset Overview + Daily Loss Monitor
- 비용 리뷰 → LLM Cost Tracking (top-10 사용자, 모델 분포)
- 인시던트 진단:
- 브로커 에러 / 지연 → Broker Health
- 분석 지연 / 큐 적체 → Worker Queue
- 사용자가 kill switch 임박 → Daily Loss Monitor (사용자별 PnL 테이블)
데이터 소스
모든 패널은 timescaledb 데이터소스(uid)를 사용합니다. 참조 테이블:
analysis_reports.cost_usd / total_tokens / model_used / statusanalysis_request_queue.status / leased_until / enqueued_atbroker_order_events.event_type / received_at / payload->latency_mspositions.realized_pnl / unrealized_pnl / asset_class / opened_attrades.timestamp / symbol
연결 파라미터는 POSTGRES_HOST / POSTGRES_USER / POSTGRES_PASSWORD /
POSTGRES_DB 환경변수로 주입되어, 로컬 docker-compose와 prod에서 같은
프로비저닝이 동작합니다.
3. 4종 알림 규칙
infra/grafana/alerting/rules.yaml에 정의:
| 규칙 UID | 트리거 | 채널 |
|---|---|---|
quantai-llm-daily-cost | SUM(cost_usd) > $10 (24h, 5분 sustained) | Telegram |
quantai-broker-5xx-rate | 5xx 비율 > 5% (5분) | Telegram |
quantai-daily-loss-imminent | 사용자별 일일 PnL% <= -4% (kill -5%) | Telegram + Email |
quantai-worker-queue-backlog | analysis_request_queue > 100 (10분 sustained) | Telegram |
라우팅은 infra/grafana/alerting/contact_points.yaml:
- 기본:
telegram-webhook→ POSThttp://api:8000/internal/grafana/webhook→AlertManager.send_message severity=critical이면서channel=~".*email.*"→email-ops추가 발송 (SMTP 설정 시)
자세한 채널/룰 변경은 Telegram 알림 참조.
4. 대시보드 추가 / 수정
# 1) JSON 편집 또는 신규 추가
$EDITOR infra/grafana/dashboards/foo.json
# 2) 신규라면 uid 새로 부여, version 1
# 3) 컨테이너 재시작
docker compose restart grafana
# 4) 검증 (CI에서도 동일 테스트)
docker compose exec api python -m pytest tests/monitoring/test_grafana_dashboards.py
provider는 30초마다 자동 reload 하므로 재시작 없이도 반영되지만, 프로비저닝 변경 시는 재시작이 안전합니다.
패널 작성 컨벤션
- 데이터소스:
{ "type": "postgres", "uid": "timescaledb" } - 시간 필터:
$__timeFrom() / $__timeTo()또는NOW() - INTERVAL. 하드코딩 literal은 테스트가 거부. - 블록 코멘트(
/* ... */) 및 trailing 코멘트 사용 금지 — SQL hygiene lint - 숫자 컬럼은 명시적 캐스팅(
::float8/::int8)
5. 알림 규칙 추가 / 수정
infra/grafana/alerting/rules.yaml은 Grafana unified-alerting v1
스키마입니다.
groups:
- orgId: 1
name: <group>
folder: quant-ai (Ops)
interval: 1m
rules:
- uid: <stable-uid>
title: <human readable>
condition: C
data: [...]
for: 5m
labels:
severity: warning
channel: telegram
annotations:
summary: ...
수정 후:
docker compose restart grafanapytest tests/monitoring/test_grafana_dashboards.py—test_alerting_rules_yaml_has_all_four_rules가 깨지면 4종 규칙이 사라진 것. 디자인 결정 없이 제거 금지.
6. 트러블슈팅
| 증상 | 원인 / 조치 |
|---|---|
| 대시보드는 떴는데 패널이 비어 있음 | DB 테이블에 데이터가 아직 없음 (분석/거래가 한 건도 없음). psql로 확인 |
Datasource error password authentication failed | POSTGRES_PASSWORD 가 Grafana env와 TimescaleDB 사이에서 불일치. 컨테이너 둘 다 재시작 |
| Telegram 알림이 안 옴 | API 로그에서 grafana_webhook_alert 검색. TELEGRAM_TOKEN 미설정이면 로그만 남고 발송 스킵 |
브리지 로그 401 missing bearer token | GRAFANA_WEBHOOK_SECRET이 API에는 설정, Grafana에는 미설정. 양쪽 일치 필요 |
| 알림이 해소 후에도 반복 | Grafana repeat_interval 기본 1h. UI에서 acknowledge 또는 short interval로 |
7. 체크리스트
대시보드/룰 변경 PR 머지 전
-
pytest tests/monitoring/test_grafana_dashboards.py tests/monitoring/test_grafana_webhook.py - 로컬에서 Grafana 재기동 후 영향 대시보드 시각 확인
- 룰 변경 시 임계를 한번 낮춰 강제 발화 → bridge
/health확인 - 신규 datasource UID 추가 없음 —
timescaledb단일 유지
프로덕션 롤아웃
-
GF_SECURITY_ADMIN_PASSWORD회전 완료 -
GRAFANA_WEBHOOK_SECRETGrafana + API 양쪽 설정 - SMTP 셋업 (이메일 채널 사용 시)
-
/internal/*외부 접근 차단 (reverse proxy / NSG) -
grafana_data볼륨 백업 일정