vault 開発 · 本番での vault 運用 · 6/7
監視と通知
なぜ監視が大事か
監視なしで動く vault の keeper は、時限爆弾のようなものです。keeper が落ちたり、接続が切れたり、ひどい売買をしたりしたら、すぐに知る必要があります。預けた人から苦情が来てから気づくのでは遅すぎます。
見張るべき指標
稼働の指標
- keeper の稼働 — プロセスは動いているか
- 最後の生存確認 — ループが最後に正常に回ったのはいつか
- WebSocket の接続 — データの配信は生きているか
- API の応答時間 — リクエストに時間がかかりすぎていないか
売買の指標
- 口座の資産 — 資産の推移を追います
- ドローダウン — 資産の最高値から今どれだけ下がっているか
- 証拠金の比率 — 証拠金をどれだけ使っているか
- ポジションの数 — 建てているポジションの数
- 含み損益 — すべてのポジションを合わせた今の損益
リスクの指標
- ポジションの最大の大きさ — どれかのポジションが上限を超えたら通知します
- レバレッジ — 実際のレバレッジがしきい値を超えたら通知します
- 資金調達料の受け払い — 1時間ごとに受け取った額と払った額を追います
監視を作る
import logging
import time
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class VaultMetrics:
equity: float = 0.0
peak_equity: float = 0.0
drawdown_pct: float = 0.0
margin_ratio: float = 0.0
num_positions: int = 0
total_pnl: float = 0.0
last_update: datetime = field(default_factory=datetime.now)
errors_last_hour: int = 0
class VaultMonitor:
def __init__(self, vault_address: str, alert_callback=None):
self.vault_address = vault_address
self.metrics = VaultMetrics()
self.alert_callback = alert_callback
self.logger = logging.getLogger("vault_monitor")
def update(self, vault_state: dict):
summary = vault_state["marginSummary"]
equity = float(summary["accountValue"])
margin_used = float(summary["totalMarginUsed"])
self.metrics.equity = equity
self.metrics.peak_equity = max(self.metrics.peak_equity, equity)
self.metrics.drawdown_pct = (
(self.metrics.peak_equity - equity) / self.metrics.peak_equity * 100
if self.metrics.peak_equity > 0 else 0
)
self.metrics.margin_ratio = margin_used / equity if equity > 0 else 1.0
self.metrics.num_positions = len(vault_state.get("assetPositions", []))
self.metrics.last_update = datetime.now()
# Check alert conditions
self._check_alerts()
def _check_alerts(self):
if self.metrics.drawdown_pct > 10:
self._alert(f"DRAWDOWN ALERT: {self.metrics.drawdown_pct:.1f}%")
if self.metrics.margin_ratio > 0.7:
self._alert(f"HIGH MARGIN: {self.metrics.margin_ratio:.1%}")
def _alert(self, message: str):
self.logger.warning(message)
if self.alert_callback:
self.alert_callback(message)
通知の送り先
本番の vault では、次の方法で通知を受け取れるようにします。
- Telegram のボット — 暗号資産のボットで最もよく使われます
- Discord の webhook — チームへの通知に向いています
- PagerDuty/OpsGenie — 本格的な本番の体制向けです
- SMS — 重大な通知(keeper の停止、清算の危険)に使います
ログのよいやり方
# Use structured logging for easy parsing
import json
import logging
from datetime import datetime
logger = logging.getLogger("vault_trades")
def log_trade(vault_address: str, action: str, coin: str, size: float,
price: float, result: dict):
log_entry = {
"timestamp": datetime.now().isoformat(),
"action": action,
"coin": coin,
"size": size,
"price": price,
"result_status": result.get("status"),
"vault": vault_address,
}
logger.info(json.dumps(log_entry))
ログはサーバーの外(CloudWatch、Datadog)に保存しましょう。サーバーが壊れても、売買の履歴を調べられます。