Skip to content

監視とパフォーマンス

概要

Trae IDEの監視機能により、アプリケーションのパフォーマンス、リソース使用量、エラーを追跡できます。このガイドでは、効果的な監視戦略の実装について説明します。

パフォーマンス監視

CPU使用量の監視

typescript
// src/monitoring/cpuMonitor.ts
export class CPUMonitor {
    private intervalId: NodeJS.Timeout | null = null;
    private readonly sampleInterval = 1000; // 1秒間隔

    start(): void {
        this.intervalId = setInterval(() => {
            const usage = process.cpuUsage();
            const memUsage = process.memoryUsage();
            
            this.logMetrics({
                cpu: {
                    user: usage.user / 1000000, // マイクロ秒からミリ秒に変換
                    system: usage.system / 1000000
                },
                memory: {
                    rss: memUsage.rss / 1024 / 1024, // バイトからMBに変換
                    heapUsed: memUsage.heapUsed / 1024 / 1024,
                    heapTotal: memUsage.heapTotal / 1024 / 1024,
                    external: memUsage.external / 1024 / 1024
                }
            });
        }, this.sampleInterval);
    }

    stop(): void {
        if (this.intervalId) {
            clearInterval(this.intervalId);
            this.intervalId = null;
        }
    }

    private logMetrics(metrics: any): void {
        console.log(`[${new Date().toISOString()}] Performance Metrics:`, metrics);
        
        // 閾値チェック
        if (metrics.memory.heapUsed > 500) { // 500MB以上
            console.warn('高いメモリ使用量が検出されました:', metrics.memory.heapUsed, 'MB');
        }
    }
}

メモリリーク検出

typescript
// src/monitoring/memoryLeakDetector.ts
export class MemoryLeakDetector {
    private snapshots: Array<{ timestamp: number; heapUsed: number }> = [];
    private readonly maxSnapshots = 10;
    private readonly checkInterval = 30000; // 30秒間隔

    start(): void {
        setInterval(() => {
            this.takeSnapshot();
            this.analyzeLeaks();
        }, this.checkInterval);
    }

    private takeSnapshot(): void {
        const memUsage = process.memoryUsage();
        const snapshot = {
            timestamp: Date.now(),
            heapUsed: memUsage.heapUsed / 1024 / 1024 // MB
        };

        this.snapshots.push(snapshot);

        // 古いスナップショットを削除
        if (this.snapshots.length > this.maxSnapshots) {
            this.snapshots.shift();
        }
    }

    private analyzeLeaks(): void {
        if (this.snapshots.length < 3) return;

        const recent = this.snapshots.slice(-3);
        const isIncreasing = recent.every((snapshot, index) => {
            if (index === 0) return true;
            return snapshot.heapUsed > recent[index - 1].heapUsed;
        });

        if (isIncreasing) {
            const increase = recent[recent.length - 1].heapUsed - recent[0].heapUsed;
            if (increase > 50) { // 50MB以上の増加
                console.warn(`メモリリークの可能性: ${increase.toFixed(2)}MB増加`);
                this.generateHeapDump();
            }
        }
    }

    private generateHeapDump(): void {
        // ヒープダンプの生成(本番環境では注意が必要)
        const v8 = require('v8');
        const fs = require('fs');
        const path = require('path');

        const heapSnapshot = v8.getHeapSnapshot();
        const fileName = `heap-${Date.now()}.heapsnapshot`;
        const filePath = path.join(process.cwd(), 'dumps', fileName);

        const fileStream = fs.createWriteStream(filePath);
        heapSnapshot.pipe(fileStream);

        console.log(`ヒープダンプを生成しました: ${filePath}`);
    }
}

アプリケーション監視

エラー追跡

typescript
// src/monitoring/errorTracker.ts
export class ErrorTracker {
    private errors: Array<{
        timestamp: number;
        error: Error;
        context?: string;
        stack?: string;
    }> = [];

    private readonly maxErrors = 100;

    track(error: Error, context?: string): void {
        const errorInfo = {
            timestamp: Date.now(),
            error,
            context,
            stack: error.stack
        };

        this.errors.push(errorInfo);

        // 古いエラーを削除
        if (this.errors.length > this.maxErrors) {
            this.errors.shift();
        }

        // エラーをログに記録
        this.logError(errorInfo);

        // 重要なエラーの場合は即座に通知
        if (this.isCriticalError(error)) {
            this.notifyCriticalError(errorInfo);
        }
    }

    private logError(errorInfo: any): void {
        console.error(`[${new Date(errorInfo.timestamp).toISOString()}] Error:`, {
            message: errorInfo.error.message,
            context: errorInfo.context,
            stack: errorInfo.stack
        });
    }

    private isCriticalError(error: Error): boolean {
        const criticalPatterns = [
            /out of memory/i,
            /segmentation fault/i,
            /uncaught exception/i,
            /database connection/i
        ];

        return criticalPatterns.some(pattern => 
            pattern.test(error.message) || pattern.test(error.name)
        );
    }

    private notifyCriticalError(errorInfo: any): void {
        // 重要なエラーの通知(メール、Slack、PagerDutyなど)
        console.error('🚨 CRITICAL ERROR DETECTED:', errorInfo.error.message);
        
        // 外部監視サービスに送信
        this.sendToExternalService(errorInfo);
    }

    private async sendToExternalService(errorInfo: any): Promise<void> {
        try {
            // 例: Sentryやその他の監視サービスに送信
            const payload = {
                timestamp: errorInfo.timestamp,
                message: errorInfo.error.message,
                stack: errorInfo.stack,
                context: errorInfo.context,
                level: 'error'
            };

            // await fetch('https://monitoring-service.com/api/errors', {
            //     method: 'POST',
            //     headers: { 'Content-Type': 'application/json' },
            //     body: JSON.stringify(payload)
            // });
        } catch (err) {
            console.error('外部監視サービスへの送信に失敗:', err);
        }
    }

    getErrorSummary(): any {
        const now = Date.now();
        const last24Hours = this.errors.filter(e => now - e.timestamp < 24 * 60 * 60 * 1000);
        const lastHour = this.errors.filter(e => now - e.timestamp < 60 * 60 * 1000);

        return {
            total: this.errors.length,
            last24Hours: last24Hours.length,
            lastHour: lastHour.length,
            mostCommon: this.getMostCommonErrors()
        };
    }

    private getMostCommonErrors(): Array<{ message: string; count: number }> {
        const errorCounts = new Map<string, number>();

        this.errors.forEach(errorInfo => {
            const message = errorInfo.error.message;
            errorCounts.set(message, (errorCounts.get(message) || 0) + 1);
        });

        return Array.from(errorCounts.entries())
            .map(([message, count]) => ({ message, count }))
            .sort((a, b) => b.count - a.count)
            .slice(0, 5);
    }
}

パフォーマンスメトリクス

typescript
// src/monitoring/performanceMetrics.ts
export class PerformanceMetrics {
    private metrics: Map<string, Array<{ timestamp: number; value: number }>> = new Map();
    private timers: Map<string, number> = new Map();

    // タイマー開始
    startTimer(name: string): void {
        this.timers.set(name, performance.now());
    }

    // タイマー終了と記録
    endTimer(name: string): number {
        const startTime = this.timers.get(name);
        if (!startTime) {
            console.warn(`タイマー '${name}' が見つかりません`);
            return 0;
        }

        const duration = performance.now() - startTime;
        this.timers.delete(name);
        this.recordMetric(name, duration);
        
        return duration;
    }

    // メトリクスの記録
    recordMetric(name: string, value: number): void {
        if (!this.metrics.has(name)) {
            this.metrics.set(name, []);
        }

        const metricArray = this.metrics.get(name)!;
        metricArray.push({
            timestamp: Date.now(),
            value
        });

        // 古いデータを削除(最新1000件のみ保持)
        if (metricArray.length > 1000) {
            metricArray.shift();
        }

        // 閾値チェック
        this.checkThresholds(name, value);
    }

    private checkThresholds(name: string, value: number): void {
        const thresholds: { [key: string]: number } = {
            'file_load_time': 1000, // 1秒
            'search_time': 500, // 0.5秒
            'compile_time': 5000, // 5秒
            'memory_usage': 1000 // 1GB
        };

        const threshold = thresholds[name];
        if (threshold && value > threshold) {
            console.warn(`パフォーマンス警告: ${name} = ${value}ms (閾値: ${threshold}ms)`);
        }
    }

    // 統計情報の取得
    getStatistics(name: string): any {
        const metricArray = this.metrics.get(name);
        if (!metricArray || metricArray.length === 0) {
            return null;
        }

        const values = metricArray.map(m => m.value);
        const sorted = [...values].sort((a, b) => a - b);

        return {
            count: values.length,
            min: Math.min(...values),
            max: Math.max(...values),
            avg: values.reduce((a, b) => a + b, 0) / values.length,
            median: sorted[Math.floor(sorted.length / 2)],
            p95: sorted[Math.floor(sorted.length * 0.95)],
            p99: sorted[Math.floor(sorted.length * 0.99)]
        };
    }

    // 全メトリクスの概要
    getAllStatistics(): any {
        const result: any = {};
        
        for (const [name] of this.metrics) {
            result[name] = this.getStatistics(name);
        }

        return result;
    }
}

リアルタイム監視

WebSocket監視ダッシュボード

typescript
// src/monitoring/dashboard.ts
import { WebSocketServer } from 'ws';

export class MonitoringDashboard {
    private wss: WebSocketServer;
    private clients: Set<any> = new Set();
    private metricsInterval: NodeJS.Timeout | null = null;

    constructor(port: number = 8080) {
        this.wss = new WebSocketServer({ port });
        this.setupWebSocketServer();
        this.startMetricsBroadcast();
    }

    private setupWebSocketServer(): void {
        this.wss.on('connection', (ws) => {
            console.log('監視クライアントが接続されました');
            this.clients.add(ws);

            // 初期データを送信
            this.sendInitialData(ws);

            ws.on('close', () => {
                console.log('監視クライアントが切断されました');
                this.clients.delete(ws);
            });

            ws.on('message', (message) => {
                try {
                    const data = JSON.parse(message.toString());
                    this.handleClientMessage(data, ws);
                } catch (error) {
                    console.error('無効なメッセージ:', error);
                }
            });
        });
    }

    private sendInitialData(ws: any): void {
        const initialData = {
            type: 'initial',
            data: {
                timestamp: Date.now(),
                system: {
                    platform: process.platform,
                    arch: process.arch,
                    nodeVersion: process.version,
                    uptime: process.uptime()
                }
            }
        };

        ws.send(JSON.stringify(initialData));
    }

    private handleClientMessage(data: any, ws: any): void {
        switch (data.type) {
            case 'request_metrics':
                this.sendCurrentMetrics(ws);
                break;
            case 'request_errors':
                this.sendErrorSummary(ws);
                break;
            default:
                console.warn('不明なメッセージタイプ:', data.type);
        }
    }

    private startMetricsBroadcast(): void {
        this.metricsInterval = setInterval(() => {
            if (this.clients.size > 0) {
                this.broadcastMetrics();
            }
        }, 5000); // 5秒間隔
    }

    private broadcastMetrics(): void {
        const metrics = this.collectCurrentMetrics();
        const message = {
            type: 'metrics_update',
            data: metrics,
            timestamp: Date.now()
        };

        this.broadcast(message);
    }

    private collectCurrentMetrics(): any {
        const memUsage = process.memoryUsage();
        const cpuUsage = process.cpuUsage();

        return {
            memory: {
                rss: memUsage.rss / 1024 / 1024,
                heapUsed: memUsage.heapUsed / 1024 / 1024,
                heapTotal: memUsage.heapTotal / 1024 / 1024,
                external: memUsage.external / 1024 / 1024
            },
            cpu: {
                user: cpuUsage.user / 1000000,
                system: cpuUsage.system / 1000000
            },
            uptime: process.uptime(),
            activeConnections: this.clients.size
        };
    }

    private sendCurrentMetrics(ws: any): void {
        const metrics = this.collectCurrentMetrics();
        const message = {
            type: 'current_metrics',
            data: metrics,
            timestamp: Date.now()
        };

        ws.send(JSON.stringify(message));
    }

    private sendErrorSummary(ws: any): void {
        // ErrorTrackerからエラー概要を取得
        const errorSummary = {
            type: 'error_summary',
            data: {
                // エラー統計データ
            },
            timestamp: Date.now()
        };

        ws.send(JSON.stringify(errorSummary));
    }

    private broadcast(message: any): void {
        const messageStr = JSON.stringify(message);
        
        this.clients.forEach(client => {
            if (client.readyState === 1) { // WebSocket.OPEN
                client.send(messageStr);
            }
        });
    }

    stop(): void {
        if (this.metricsInterval) {
            clearInterval(this.metricsInterval);
        }
        
        this.wss.close();
    }
}

監視ダッシュボードHTML

html
<!-- monitoring-dashboard.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Trae IDE 監視ダッシュボード</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .dashboard {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
            gap: 20px;
        }
        .card {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .card h3 {
            margin-top: 0;
            color: #333;
        }
        .metric {
            display: flex;
            justify-content: space-between;
            margin: 10px 0;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 4px;
        }
        .metric-value {
            font-weight: bold;
            color: #007bff;
        }
        .status-indicator {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            display: inline-block;
            margin-right: 8px;
        }
        .status-good { background-color: #28a745; }
        .status-warning { background-color: #ffc107; }
        .status-error { background-color: #dc3545; }
        .chart-container {
            position: relative;
            height: 300px;
        }
    </style>
</head>
<body>
    <h1>Trae IDE 監視ダッシュボード</h1>
    
    <div class="dashboard">
        <!-- システム情報 -->
        <div class="card">
            <h3>システム情報</h3>
            <div class="metric">
                <span>プラットフォーム:</span>
                <span class="metric-value" id="platform">-</span>
            </div>
            <div class="metric">
                <span>アーキテクチャ:</span>
                <span class="metric-value" id="arch">-</span>
            </div>
            <div class="metric">
                <span>Node.js バージョン:</span>
                <span class="metric-value" id="nodeVersion">-</span>
            </div>
            <div class="metric">
                <span>稼働時間:</span>
                <span class="metric-value" id="uptime">-</span>
            </div>
        </div>

        <!-- メモリ使用量 -->
        <div class="card">
            <h3>メモリ使用量</h3>
            <div class="metric">
                <span>RSS:</span>
                <span class="metric-value" id="memoryRss">-</span>
            </div>
            <div class="metric">
                <span>ヒープ使用量:</span>
                <span class="metric-value" id="memoryHeapUsed">-</span>
            </div>
            <div class="metric">
                <span>ヒープ合計:</span>
                <span class="metric-value" id="memoryHeapTotal">-</span>
            </div>
            <div class="metric">
                <span>外部メモリ:</span>
                <span class="metric-value" id="memoryExternal">-</span>
            </div>
        </div>

        <!-- CPU使用量 -->
        <div class="card">
            <h3>CPU使用量</h3>
            <div class="metric">
                <span>ユーザー時間:</span>
                <span class="metric-value" id="cpuUser">-</span>
            </div>
            <div class="metric">
                <span>システム時間:</span>
                <span class="metric-value" id="cpuSystem">-</span>
            </div>
        </div>

        <!-- 接続状況 -->
        <div class="card">
            <h3>接続状況</h3>
            <div class="metric">
                <span>
                    <span class="status-indicator" id="connectionStatus"></span>
                    WebSocket接続:
                </span>
                <span class="metric-value" id="connectionState">切断</span>
            </div>
            <div class="metric">
                <span>アクティブ接続数:</span>
                <span class="metric-value" id="activeConnections">-</span>
            </div>
        </div>

        <!-- メモリ使用量グラフ -->
        <div class="card">
            <h3>メモリ使用量推移</h3>
            <div class="chart-container">
                <canvas id="memoryChart"></canvas>
            </div>
        </div>

        <!-- CPU使用量グラフ -->
        <div class="card">
            <h3>CPU使用量推移</h3>
            <div class="chart-container">
                <canvas id="cpuChart"></canvas>
            </div>
        </div>
    </div>

    <script>
        class MonitoringClient {
            constructor() {
                this.ws = null;
                this.memoryChart = null;
                this.cpuChart = null;
                this.memoryData = [];
                this.cpuData = [];
                this.maxDataPoints = 50;
                
                this.initCharts();
                this.connect();
            }

            connect() {
                try {
                    this.ws = new WebSocket('ws://localhost:8080');
                    
                    this.ws.onopen = () => {
                        console.log('監視サーバーに接続しました');
                        this.updateConnectionStatus(true);
                    };

                    this.ws.onmessage = (event) => {
                        const message = JSON.parse(event.data);
                        this.handleMessage(message);
                    };

                    this.ws.onclose = () => {
                        console.log('監視サーバーから切断されました');
                        this.updateConnectionStatus(false);
                        
                        // 5秒後に再接続を試行
                        setTimeout(() => this.connect(), 5000);
                    };

                    this.ws.onerror = (error) => {
                        console.error('WebSocketエラー:', error);
                        this.updateConnectionStatus(false);
                    };
                } catch (error) {
                    console.error('接続エラー:', error);
                    this.updateConnectionStatus(false);
                }
            }

            handleMessage(message) {
                switch (message.type) {
                    case 'initial':
                        this.updateSystemInfo(message.data.system);
                        break;
                    case 'metrics_update':
                    case 'current_metrics':
                        this.updateMetrics(message.data);
                        break;
                }
            }

            updateSystemInfo(system) {
                document.getElementById('platform').textContent = system.platform;
                document.getElementById('arch').textContent = system.arch;
                document.getElementById('nodeVersion').textContent = system.nodeVersion;
                this.updateUptime(system.uptime);
            }

            updateMetrics(metrics) {
                // メモリ情報更新
                document.getElementById('memoryRss').textContent = `${metrics.memory.rss.toFixed(2)} MB`;
                document.getElementById('memoryHeapUsed').textContent = `${metrics.memory.heapUsed.toFixed(2)} MB`;
                document.getElementById('memoryHeapTotal').textContent = `${metrics.memory.heapTotal.toFixed(2)} MB`;
                document.getElementById('memoryExternal').textContent = `${metrics.memory.external.toFixed(2)} MB`;

                // CPU情報更新
                document.getElementById('cpuUser').textContent = `${metrics.cpu.user.toFixed(2)} ms`;
                document.getElementById('cpuSystem').textContent = `${metrics.cpu.system.toFixed(2)} ms`;

                // 接続情報更新
                document.getElementById('activeConnections').textContent = metrics.activeConnections || '-';
                
                this.updateUptime(metrics.uptime);
                this.updateCharts(metrics);
            }

            updateUptime(uptime) {
                const hours = Math.floor(uptime / 3600);
                const minutes = Math.floor((uptime % 3600) / 60);
                const seconds = Math.floor(uptime % 60);
                document.getElementById('uptime').textContent = `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
            }

            updateConnectionStatus(connected) {
                const statusElement = document.getElementById('connectionStatus');
                const stateElement = document.getElementById('connectionState');
                
                if (connected) {
                    statusElement.className = 'status-indicator status-good';
                    stateElement.textContent = '接続中';
                } else {
                    statusElement.className = 'status-indicator status-error';
                    stateElement.textContent = '切断';
                }
            }

            initCharts() {
                // メモリチャート
                const memoryCtx = document.getElementById('memoryChart').getContext('2d');
                this.memoryChart = new Chart(memoryCtx, {
                    type: 'line',
                    data: {
                        labels: [],
                        datasets: [{
                            label: 'ヒープ使用量 (MB)',
                            data: [],
                            borderColor: 'rgb(75, 192, 192)',
                            backgroundColor: 'rgba(75, 192, 192, 0.2)',
                            tension: 0.1
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        scales: {
                            y: {
                                beginAtZero: true
                            }
                        }
                    }
                });

                // CPUチャート
                const cpuCtx = document.getElementById('cpuChart').getContext('2d');
                this.cpuChart = new Chart(cpuCtx, {
                    type: 'line',
                    data: {
                        labels: [],
                        datasets: [{
                            label: 'ユーザー時間 (ms)',
                            data: [],
                            borderColor: 'rgb(255, 99, 132)',
                            backgroundColor: 'rgba(255, 99, 132, 0.2)',
                            tension: 0.1
                        }, {
                            label: 'システム時間 (ms)',
                            data: [],
                            borderColor: 'rgb(54, 162, 235)',
                            backgroundColor: 'rgba(54, 162, 235, 0.2)',
                            tension: 0.1
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        scales: {
                            y: {
                                beginAtZero: true
                            }
                        }
                    }
                });
            }

            updateCharts(metrics) {
                const now = new Date().toLocaleTimeString();

                // メモリチャート更新
                this.memoryChart.data.labels.push(now);
                this.memoryChart.data.datasets[0].data.push(metrics.memory.heapUsed);

                if (this.memoryChart.data.labels.length > this.maxDataPoints) {
                    this.memoryChart.data.labels.shift();
                    this.memoryChart.data.datasets[0].data.shift();
                }

                this.memoryChart.update('none');

                // CPUチャート更新
                this.cpuChart.data.labels.push(now);
                this.cpuChart.data.datasets[0].data.push(metrics.cpu.user);
                this.cpuChart.data.datasets[1].data.push(metrics.cpu.system);

                if (this.cpuChart.data.labels.length > this.maxDataPoints) {
                    this.cpuChart.data.labels.shift();
                    this.cpuChart.data.datasets[0].data.shift();
                    this.cpuChart.data.datasets[1].data.shift();
                }

                this.cpuChart.update('none');
            }
        }

        // 監視クライアントを初期化
        const monitoringClient = new MonitoringClient();
    </script>
</body>
</html>

アラートシステム

アラート設定

typescript
// src/monitoring/alertSystem.ts
export interface AlertRule {
    name: string;
    condition: (metrics: any) => boolean;
    severity: 'low' | 'medium' | 'high' | 'critical';
    cooldown: number; // ミリ秒
    actions: AlertAction[];
}

export interface AlertAction {
    type: 'email' | 'slack' | 'webhook' | 'log';
    config: any;
}

export class AlertSystem {
    private rules: AlertRule[] = [];
    private lastAlertTimes: Map<string, number> = new Map();

    addRule(rule: AlertRule): void {
        this.rules.push(rule);
    }

    checkAlerts(metrics: any): void {
        const now = Date.now();

        this.rules.forEach(rule => {
            const lastAlertTime = this.lastAlertTimes.get(rule.name) || 0;
            
            // クールダウン期間中はスキップ
            if (now - lastAlertTime < rule.cooldown) {
                return;
            }

            if (rule.condition(metrics)) {
                this.triggerAlert(rule, metrics);
                this.lastAlertTimes.set(rule.name, now);
            }
        });
    }

    private async triggerAlert(rule: AlertRule, metrics: any): Promise<void> {
        console.log(`🚨 アラート発生: ${rule.name} (重要度: ${rule.severity})`);

        const alertData = {
            rule: rule.name,
            severity: rule.severity,
            timestamp: new Date().toISOString(),
            metrics,
            message: this.generateAlertMessage(rule, metrics)
        };

        // 各アクションを実行
        for (const action of rule.actions) {
            try {
                await this.executeAction(action, alertData);
            } catch (error) {
                console.error(`アラートアクション実行エラー (${action.type}):`, error);
            }
        }
    }

    private generateAlertMessage(rule: AlertRule, metrics: any): string {
        switch (rule.name) {
            case 'high_memory_usage':
                return `メモリ使用量が高くなっています: ${metrics.memory.heapUsed.toFixed(2)}MB`;
            case 'high_cpu_usage':
                return `CPU使用量が高くなっています: ユーザー ${metrics.cpu.user.toFixed(2)}ms, システム ${metrics.cpu.system.toFixed(2)}ms`;
            case 'error_rate_high':
                return `エラー率が高くなっています: ${metrics.errorRate}%`;
            default:
                return `アラート条件が満たされました: ${rule.name}`;
        }
    }

    private async executeAction(action: AlertAction, alertData: any): Promise<void> {
        switch (action.type) {
            case 'email':
                await this.sendEmail(action.config, alertData);
                break;
            case 'slack':
                await this.sendSlackMessage(action.config, alertData);
                break;
            case 'webhook':
                await this.callWebhook(action.config, alertData);
                break;
            case 'log':
                this.logAlert(alertData);
                break;
        }
    }

    private async sendEmail(config: any, alertData: any): Promise<void> {
        // メール送信の実装
        console.log('メール送信:', config.to, alertData.message);
    }

    private async sendSlackMessage(config: any, alertData: any): Promise<void> {
        // Slack通知の実装
        const payload = {
            text: `🚨 ${alertData.rule}`,
            attachments: [{
                color: this.getSeverityColor(alertData.severity),
                fields: [{
                    title: 'メッセージ',
                    value: alertData.message,
                    short: false
                }, {
                    title: '時刻',
                    value: alertData.timestamp,
                    short: true
                }, {
                    title: '重要度',
                    value: alertData.severity,
                    short: true
                }]
            }]
        };

        // await fetch(config.webhookUrl, {
        //     method: 'POST',
        //     headers: { 'Content-Type': 'application/json' },
        //     body: JSON.stringify(payload)
        // });
    }

    private async callWebhook(config: any, alertData: any): Promise<void> {
        // Webhook呼び出しの実装
        // await fetch(config.url, {
        //     method: 'POST',
        //     headers: { 'Content-Type': 'application/json' },
        //     body: JSON.stringify(alertData)
        // });
    }

    private logAlert(alertData: any): void {
        console.log(`[ALERT] ${alertData.timestamp} - ${alertData.rule}: ${alertData.message}`);
    }

    private getSeverityColor(severity: string): string {
        switch (severity) {
            case 'low': return 'good';
            case 'medium': return 'warning';
            case 'high': return 'danger';
            case 'critical': return '#ff0000';
            default: return '#cccccc';
        }
    }
}

// アラートルールの設定例
export function setupDefaultAlerts(alertSystem: AlertSystem): void {
    // 高メモリ使用量アラート
    alertSystem.addRule({
        name: 'high_memory_usage',
        condition: (metrics) => metrics.memory.heapUsed > 500, // 500MB以上
        severity: 'medium',
        cooldown: 5 * 60 * 1000, // 5分
        actions: [
            { type: 'log', config: {} },
            { type: 'slack', config: { webhookUrl: 'YOUR_SLACK_WEBHOOK_URL' } }
        ]
    });

    // 重要メモリ使用量アラート
    alertSystem.addRule({
        name: 'critical_memory_usage',
        condition: (metrics) => metrics.memory.heapUsed > 1000, // 1GB以上
        severity: 'critical',
        cooldown: 2 * 60 * 1000, // 2分
        actions: [
            { type: 'log', config: {} },
            { type: 'slack', config: { webhookUrl: 'YOUR_SLACK_WEBHOOK_URL' } },
            { type: 'email', config: { to: 'admin@example.com' } }
        ]
    });

    // 高CPU使用量アラート
    alertSystem.addRule({
        name: 'high_cpu_usage',
        condition: (metrics) => metrics.cpu.user + metrics.cpu.system > 1000, // 1秒以上
        severity: 'medium',
        cooldown: 3 * 60 * 1000, // 3分
        actions: [
            { type: 'log', config: {} }
        ]
    });
}

統合監視システム

typescript
// src/monitoring/monitoringSystem.ts
export class MonitoringSystem {
    private cpuMonitor: CPUMonitor;
    private memoryLeakDetector: MemoryLeakDetector;
    private errorTracker: ErrorTracker;
    private performanceMetrics: PerformanceMetrics;
    private alertSystem: AlertSystem;
    private dashboard: MonitoringDashboard;

    constructor() {
        this.cpuMonitor = new CPUMonitor();
        this.memoryLeakDetector = new MemoryLeakDetector();
        this.errorTracker = new ErrorTracker();
        this.performanceMetrics = new PerformanceMetrics();
        this.alertSystem = new AlertSystem();
        this.dashboard = new MonitoringDashboard();

        this.setupDefaultAlerts();
        this.startMonitoring();
    }

    private setupDefaultAlerts(): void {
        setupDefaultAlerts(this.alertSystem);
    }

    private startMonitoring(): void {
        this.cpuMonitor.start();
        this.memoryLeakDetector.start();

        // 定期的にアラートをチェック
        setInterval(() => {
            const metrics = this.collectAllMetrics();
            this.alertSystem.checkAlerts(metrics);
        }, 30000); // 30秒間隔
    }

    private collectAllMetrics(): any {
        const memUsage = process.memoryUsage();
        const cpuUsage = process.cpuUsage();

        return {
            memory: {
                rss: memUsage.rss / 1024 / 1024,
                heapUsed: memUsage.heapUsed / 1024 / 1024,
                heapTotal: memUsage.heapTotal / 1024 / 1024,
                external: memUsage.external / 1024 / 1024
            },
            cpu: {
                user: cpuUsage.user / 1000000,
                system: cpuUsage.system / 1000000
            },
            errors: this.errorTracker.getErrorSummary(),
            performance: this.performanceMetrics.getAllStatistics()
        };
    }

    // 公開メソッド
    trackError(error: Error, context?: string): void {
        this.errorTracker.track(error, context);
    }

    startTimer(name: string): void {
        this.performanceMetrics.startTimer(name);
    }

    endTimer(name: string): number {
        return this.performanceMetrics.endTimer(name);
    }

    recordMetric(name: string, value: number): void {
        this.performanceMetrics.recordMetric(name, value);
    }

    getHealthStatus(): any {
        const metrics = this.collectAllMetrics();
        
        return {
            status: this.determineOverallHealth(metrics),
            timestamp: new Date().toISOString(),
            metrics,
            uptime: process.uptime()
        };
    }

    private determineOverallHealth(metrics: any): 'healthy' | 'warning' | 'critical' {
        if (metrics.memory.heapUsed > 1000) return 'critical';
        if (metrics.memory.heapUsed > 500) return 'warning';
        if (metrics.errors.lastHour > 10) return 'warning';
        if (metrics.errors.lastHour > 50) return 'critical';
        
        return 'healthy';
    }

    stop(): void {
        this.cpuMonitor.stop();
        this.dashboard.stop();
    }
}

// グローバル監視システムのインスタンス
export const globalMonitoring = new MonitoringSystem();

このガイドを参考に、Trae IDEの包括的な監視システムを構築し、アプリケーションの健全性とパフォーマンスを効果的に追跡してください。

究極の AI 駆動 IDE 学習ガイド