Feature 36: 自動リカバリーシステム
Copyright: 2026 Moonlight Technologies Inc.
Author: Masahiro Aoki
実装日: 2026年2月20日
バージョン: 1.0.0
ステータス: ✅ 実装済み
概要
EvoSpikeNet の自動リカバリーシステム(Feature 36)は、AI ベースの異常検知と自動プレイブック実行を組み合わせ、システム障害の平均復旧時間(MTTR)を 80% 削減することを目的としています。
バックグラウンドで継続的にシステムメトリクスを監視し、異常を検知した場合は根本原因を分析して事前定義されたリカバリープレイブックを自動実行します。
アーキテクチャ
システムメトリクス
│
▼
┌─────────────────┐
│ AnomalyDetector │ ← Z スコア + EWMA による異常検知
│ (per metric) │
└────────┬────────┘
│ 異常検出
▼
┌─────────────────┐
│ RootCauseAnalyzer│ ← ルールベース根本原因分析
└────────┬────────┘
│ FailureCategory
▼
┌─────────────────┐
│ Recovery │ ← プレイブック選択・実行
│ Playbooks │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Incident │ ← インシデント記録・追跡
│ Tracking │
└─────────────────┘
コアコンポーネント
AnomalyDetector
Z スコアおよび EWMA(指数加重移動平均)を用いてメトリクスの異常を検知します。 インスタンス化時にはウィンドウ長のみを指定し、しきい値等はクラス定数で制御されます。
<!-- from evospikenet.auto_recovery import AnomalyDetector -->
# デフォルトの 60 秒窓を使用
# Z_THRESHOLD=3.0, EWMA_ALPHA=0.15, MIN_SAMPLES=10 はクラス属性として定義
# 必要であればサブクラス化して上書きできます。
detector = AnomalyDetector(window=60)
# メトリクス値を更新し、異常を検出(True が返れば異常)
is_anomaly = detector.update("cpu_percent", 95.0)
主要プロパティ:
| 属性 | デフォルト | 説明 |
|---|---|---|
AnomalyDetector.Z_THRESHOLD |
3.0 | 異常判定の Z スコア閾値 |
AnomalyDetector.EWMA_ALPHA |
0.15 | EWMA の平滑化係数 |
AnomalyDetector.MIN_SAMPLES |
10 | 異常判定に必要な最小サンプル数 |
window (コンストラクタ引数) |
60 | 履歴を保持するサンプル数 |
RootCauseAnalyzer
収集したメトリクスから障害カテゴリ、信頼度、説明を判定します。
<!-- TODO: update or remove - import failrt RootCauseAnalyzer, FailureCategory -->
analyzer = RootCauseAnalyzer()
category, confidence, explanation = analyzer.analyze({
"cpu_percent": 95.0,
"memory_percent": 45.0,
"db_connected": True,
"error_rate": 0.05,
})
# → (FailureCategory.CPU_OVERLOAD, 0.80, "CPU at 95.0%")
判定可能な障害カテゴリと基準:
| カテゴリ | 説明 | 判定条件 (analyze 実装) |
|---|---|---|
memory_exhaustion |
メモリ枯渇 | memory_percent ≥ 85% |
oom_kill |
OOM キルリスク | memory_percent ≥ 95% |
cpu_overload |
CPU 過負荷 | cpu_percent ≥ 95% |
disk_full |
ディスク容量不足 | disk_percent ≥ 90% |
database_error |
DB 接続障害 | db_connected == False |
zenoh_disconnect |
Zenoh 切断 | zenoh_connected == False |
model_crash |
モデルクラッシュ | model_ready == False |
unknown |
その他/不明 | 上記以外、エラーレートが高い場合など |
Recovery Playbooks
障害カテゴリごとに試みられる自動回復アクションの順序リストを定義します。
| 回復アクション | 説明 |
|---|---|
RESTART_SERVICE |
サービスの再起動 |
RELOAD_MODEL |
モデルの再読込 |
RESTORE_SNAPSHOT |
スナップショットから復元 |
SCALE_DOWN |
リソース削減 |
CLEAR_CACHE |
キャッシュクリア |
RECONNECT_ZENOH |
Zenoh 再接続 |
RECONNECT_DB |
DB 再接続 |
FREE_DISK |
ディスク空き容量確保 |
NOTIFY_ONLY |
非常時に通知のみ実施(オペレーターへ) |
AutoRecoveryEngine
バックグラウンドスレッドでメトリクスを監視し、インシデントライフサイクルを管理します。
<!-- モジュール 'evospikenet' が見つかりません。パッケージ内の移動/名前変更を確認してください -->
<!-PIサーバー起動時に自動実行)
auto_recovery_engine.start()
# メトリクスを手動で報告(インシデントが作成された場合は返す)
incident = auto_recovery_engine.report_metrics(
cpu_percent=45.0,
memory_percent=60.0,
disk_percent=55.0,
db_connected=True,
zenoh_connected=True,
model_ready=True,
error_rate=0.01,
)
# インシデント一覧取得
incidents = auto_recovery_engine.get_incidents()
# インシデントステータス変更
auto_recovery_engine.acknowledge_incident("incident-id")
auto_recovery_engine.resolve_incident("incident-id", "手動でプロセスを再起動")
REST API
GET /api/recovery/status
リカバリーエンジンの現在のステータスを返します。
レスポンス例:
{
"total_incidents": 12,
"open_incidents": 1,
"acknowledged_incidents": 0,
"resolved_incidents": 9,
"auto_resolved_incidents": 2,
"mttr_seconds": 145.2,
"monitoring_interval_seconds": 30,
"enabled_categories": ["cpu_overload", "memory_exhaustion", "database_error"]
}
GET /api/recovery/incidents
クエリパラメータ: status, severity, limit
GET /api/recovery/incidents/{id}
POST /api/recovery/incidents/{id}/acknowledge
POST /api/recovery/incidents/{id}/resolve
リクエストボディ (任意):
{ "resolution_note": "手動でサービスを再起動しました" }
POST /api/recovery/trigger
メトリクスをもとに手動で異常診断をトリガーします。
リクエストボディ:
{
"cpu_percent": 95.0,
"memory_percent": 80.0,
"disk_percent": 60.0,
"db_connected": false,
"zenoh_connected": true,
"model_ready": true,
"error_rate": 0.15
}
レスポンス (インシデントあり):
{
"status": "incident_created",
"incident": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"category": "database_error",
"severity": "critical",
"status": "open",
"actions_taken": ["RECONNECT_DB", "NOTIFY_ONLY"]
}
}
レスポンス (正常):
{ "status": "no_anomaly_detected" }
設定
config/settings.yaml (各プロジェクトで任意に読込):
auto_recovery:
enabled: true
monitoring_interval_seconds: 30 # AutoRecoveryEngine.MONITORING_INTERVAL
state_file: "data/recovery/auto_recovery_state.json" # AutoRecoveryEngine.STATE_FILE
detector_window: 60 # AnomalyDetector の履歴長
thresholds:
cpu_percent: 90.0
memory_percent: 85.0
disk_percent: 90.0
error_rate: 0.1
インシデント構造
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"category": "memory_exhaustion",
"severity": "high",
"status": "open",
"message": "Memory usage abnormally high: 92.3%",
"detected_at": "2026-02-20T10:00:00Z",
"resolved_at": null,
"ttd_seconds": null,
"ttr_seconds": null,
"actions_taken": ["CLEAR_CACHE", "NOTIFY_ONLY"],
"root_cause": "memory_exhaustion",
"metrics_snapshot": {
"memory_percent": 92.3,
"cpu_percent": 45.0
}
}
ステータス遷移:
open → acknowledged → resolved
└──────────────────→ auto_resolved
テスト
# ユニットテスト
pytest tests/unit/test_auto_recovery.py -v
# 結合テスト
pytest tests/integration/test_features_36_39_40_integration.py::TestAutoRecoveryEndpoints -v
# システムテスト
pytest tests/system/test_features_36_39_40_system.py::TestE2EIncidentAuditFlow -v
# 性能テスト
pytest tests/performance/test_features_36_39_40_performance.py::TestAutoRecoveryEnginePerformance -v
関連ドキュメント
- SDK API Reference - Feature 36
auto_recovery_sdk.py- 監査ログ
- 地理的分散ノード管理