見出し画像

第九回:マイクロフロントエンドの監視と運用

「本番環境でエラーが起きても、どのアプリが原因か分からない...」
「パフォーマンスの問題はどうやって見つければいい?」
「複数のアプリを効率的に監視するには?」

マイクロフロントエンドを実運用する上で、適切な監視体制は不可欠です。
今回は、効果的な監視と運用の方法を具体的に見ていきましょう。

監視すべき3つの重要指標

1. エラー監視

// エラー監視の実装例
class ErrorTracker {
  constructor() {
    // グローバルエラーのキャッチ
    window.addEventListener('error', (event) => {
      this.handleError(event.error);
    });

    // Promiseエラーのキャッチ
    window.addEventListener('unhandledrejection', (event) => {
      this.handleError(event.reason);
    });
  }

  handleError(error) {
    // エラー情報の収集
    const errorInfo = {
      app: this.detectApp(),  // どのアプリでエラーが発生したか
      message: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString(),
      userInfo: this.getUserInfo()
    };

    // エラー情報の送信
    this.sendToAnalytics(errorInfo);
  }
}

// 使用例
const errorTracker = new ErrorTracker();

2. パフォーマンス監視

// パフォーマンス監視の実装例
class PerformanceMonitor {
  constructor() {
    // Core Web Vitalsの監視
    this.observeCoreWebVitals();
    
    // カスタムメトリクスの監視
    this.observeCustomMetrics();
  }

  observeCoreWebVitals() {
    new PerformanceObserver((list) => {
      list.getEntries().forEach(metric => {
        // LCP, FID, CLSなどの計測
        this.sendMetric({
          name: metric.name,
          value: metric.value,
          app: this.detectApp()
        });
      });
    }).observe({ entryTypes: ['web-vitals'] });
  }

  observeCustomMetrics() {
    // アプリごとのロード時間
    this.measureAppLoadTime();
    
    // インタラクションの応答時間
    this.measureInteractionTime();
  }
}

3. ユーザー行動分析

// ユーザー行動分析の実装例
class UserBehaviorTracker {
  constructor() {
    this.tracks = [];
  }

  // ユーザーの行動を記録
  trackEvent(event) {
    const eventData = {
      type: event.type,
      app: this.detectApp(),
      timestamp: new Date().toISOString(),
      path: window.location.pathname,
      // その他の関連情報
    };

    this.tracks.push(eventData);
    
    // 定期的にサーバーに送信
    if (this.tracks.length >= 10) {
      this.sendTracks();
    }
  }
}

効率的な運用のためのツール

1. 集中監視ダッシュボード

// ダッシュボードのデータ収集
class Dashboard {
  async collectMetrics() {
    const metrics = {
      errors: await this.getErrorMetrics(),
      performance: await this.getPerformanceMetrics(),
      userBehavior: await this.getUserMetrics()
    };

    // アプリごとの状態を可視化
    this.updateDashboard(metrics);
  }

  // リアルタイムアラートの設定
  setAlerts() {
    const alertRules = {
      errorRate: {
        threshold: 0.01,  // エラー率1%以上
        action: this.notifyTeam
      },
      loadTime: {
        threshold: 3000,  // ロード時間3秒以上
        action: this.notifyTeam
      }
    };
  }
}

2. ログ分析システム

// 構造化ログの実装
class Logger {
  log(level, message, context = {}) {
    const logEntry = {
      timestamp: new Date().toISOString(),
      level,
      message,
      app: context.app || this.detectApp(),
      correlationId: context.correlationId || this.generateId(),
      // その他のコンテキスト情報
    };

    // ログの保存と分析
    this.processLog(logEntry);
  }

  // ログの検索と分析
  async analyze(query) {
    // 特定パターンの検出
    // トレンド分析
    // 異常検知
  }
}

インシデント対応の自動化

1. 自動復旧の仕組み

// 自動復旧システムの実装
class AutoRecovery {
  async checkHealth(app) {
    const health = await this.performHealthCheck(app);
    
    if (!health.isHealthy) {
      await this.tryRecover(app);
    }
  }

  async tryRecover(app) {
    // 段階的な復旧手順
    const steps = [
      this.reloadApp,
      this.clearCache,
      this.rollbackVersion
    ];

    for (const step of steps) {
      if (await step(app)) {
        return true;  // 復旧成功
      }
    }

    // 全ての手順が失敗した場合
    await this.notifyTeam(app);
    return false;
  }
}

2. チーム通知の自動化

// インシデント通知システム
class IncidentNotifier {
  constructor() {
    this.channels = {
      slack: new SlackNotifier(),
      email: new EmailNotifier(),
      sms: new SMSNotifier()
    };
  }

  // 重要度に応じた通知
  async notify(incident) {
    switch (incident.severity) {
      case 'high':
        // 全チャンネルに通知
        await Promise.all(
          Object.values(this.channels)
            .map(c => c.notify(incident))
        );
        break;
      
      case 'medium':
        // Slackとメールのみ
        await Promise.all([
          this.channels.slack.notify(incident),
          this.channels.email.notify(incident)
        ]);
        break;
      
      case 'low':
        // Slackのみ
        await this.channels.slack.notify(incident);
        break;
    }
  }
}

運用のベストプラクティス

  1. 予防的な監視

    • 異常の早期検出

    • トレンド分析による予測

    • 定期的な健全性チェック

  2. 効率的なトラブルシューティング

    • 構造化されたログ

    • 相関ID(Correlation ID)の活用

    • 再現手順の自動記録

  3. 継続的な改善

    • インシデントの振り返り

    • メトリクスに基づく改善

    • 自動化の範囲拡大

まとめ

マイクロフロントエンドの運用では

  • 適切な監視指標の設定

  • 効率的な運用ツールの活用

  • インシデント対応の自動化

  • 継続的な改善サイクル

が重要です。

いいなと思ったら応援しよう!