監視とパフォーマンス
概要
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の包括的な監視システムを構築し、アプリケーションの健全性とパフォーマンスを効果的に追跡してください。