Skip to content本文へ移動

Vault Development · Production Vault Operations · 6/7

Monitoring & Alerts

Why Monitoring Matters

A vault keeper running without monitoring is a ticking time bomb. If the keeper crashes, loses connection, or makes a bad trade, you need to know immediately — not when depositors start complaining.

Key Metrics to Monitor

Health Metrics

Trading Metrics

Risk Metrics

Implementing Monitoring

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)

Alert Channels

For production vaults, set up alerts via:

Logging Best Practices

# 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))

Store logs externally (CloudWatch, Datadog) so you can analyze trading history even if the server dies.

vault 開発 · 本番での vault 運用 · 6/7

監視と通知

なぜ監視が大事か

監視なしで動く vault の keeper は、時限爆弾のようなものです。keeper が落ちたり、接続が切れたり、ひどい売買をしたりしたら、すぐに知る必要があります。預けた人から苦情が来てから気づくのでは遅すぎます。

見張るべき指標

稼働の指標

売買の指標

リスクの指標

監視を作る

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 では、次の方法で通知を受け取れるようにします。

ログのよいやり方

# 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)に保存しましょう。サーバーが壊れても、売買の履歴を調べられます。