Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Kiro Performance Analyzer | |
| Анализирует логи мониторинга и даёт рекомендации по оптимизации. | |
| """ | |
| import csv | |
| import sys | |
| from collections import defaultdict | |
| from datetime import datetime | |
| from pathlib import Path | |
| from typing import Dict, List, Tuple | |
| def analyze_memory_growth(log_file: Path) -> Dict: | |
| """Анализирует рост памяти по процессам.""" | |
| process_snapshots = defaultdict(list) | |
| with open(log_file, 'r', encoding='utf-8') as f: | |
| reader = csv.DictReader(f) | |
| for row in reader: | |
| pid = row['pid'] | |
| timestamp = datetime.fromisoformat(row['timestamp']) | |
| memory = float(row['memory_mb']) | |
| process_type = row['type'] | |
| process_snapshots[pid].append({ | |
| 'timestamp': timestamp, | |
| 'memory': memory, | |
| 'type': process_type | |
| }) | |
| # Анализ роста | |
| leaks = [] | |
| for pid, snapshots in process_snapshots.items(): | |
| if len(snapshots) < 2: | |
| continue | |
| first = snapshots[0] | |
| last = snapshots[-1] | |
| growth = last['memory'] - first['memory'] | |
| duration = (last['timestamp'] - first['timestamp']).total_seconds() | |
| if duration > 0: | |
| growth_rate = growth / (duration / 60) # MB/min | |
| if growth_rate > 50: # > 50 MB/min | |
| leaks.append({ | |
| 'pid': pid, | |
| 'type': first['type'], | |
| 'initial': first['memory'], | |
| 'final': last['memory'], | |
| 'growth': growth, | |
| 'rate': growth_rate, | |
| 'duration': duration | |
| }) | |
| return { | |
| 'leaks': sorted(leaks, key=lambda x: x['rate'], reverse=True), | |
| 'total_processes': len(process_snapshots) | |
| } | |
| def get_recommendations(analysis: Dict) -> List[str]: | |
| """Генерирует рекомендации на основе анализа.""" | |
| recommendations = [] | |
| leaks = analysis['leaks'] | |
| if not leaks: | |
| recommendations.append("✅ Утечек памяти не обнаружено") | |
| return recommendations | |
| for leak in leaks: | |
| if "Extension Host" in leak['type']: | |
| recommendations.append( | |
| f"🔴 КРИТИЧНО: Extension Host (PID {leak['pid']}) течёт {leak['rate']:.1f} MB/min\n" | |
| f" Начало: {leak['initial']:.0f} MB → Конец: {leak['final']:.0f} MB (+{leak['growth']:.0f} MB)\n" | |
| f" Действия:\n" | |
| f" 1. Ctrl+Shift+P → 'Developer: Show Running Extensions'\n" | |
| f" 2. Отключи расширения с большим потреблением памяти\n" | |
| f" 3. Перезапусти Extension Host: Ctrl+Shift+P → 'Developer: Restart Extension Host'" | |
| ) | |
| elif "Webview Renderer" in leak['type']: | |
| recommendations.append( | |
| f"🟠 Webview Renderer (PID {leak['pid']}) течёт {leak['rate']:.1f} MB/min\n" | |
| f" Начало: {leak['initial']:.0f} MB → Конец: {leak['final']:.0f} MB (+{leak['growth']:.0f} MB)\n" | |
| f" Действия:\n" | |
| f" 1. Закрой лишние webview панели (превью, терминалы)\n" | |
| f" 2. Перезагрузи окно: Ctrl+Shift+P → 'Developer: Reload Window'" | |
| ) | |
| elif "Main Process" in leak['type']: | |
| recommendations.append( | |
| f"🟡 Main Process (PID {leak['pid']}) течёт {leak['rate']:.1f} MB/min\n" | |
| f" Начало: {leak['initial']:.0f} MB → Конец: {leak['final']:.0f} MB (+{leak['growth']:.0f} MB)\n" | |
| f" Действия: Перезапусти Kiro" | |
| ) | |
| return recommendations | |
| def main(): | |
| log_dir = Path.home() / ".kiro-manager-wb" | |
| log_files = sorted(log_dir.glob("kiro_monitor_*.csv"), key=lambda p: p.stat().st_mtime, reverse=True) | |
| if not log_files: | |
| print("❌ Логи мониторинга не найдены") | |
| print(f"Запусти: python autoreg/scripts/kiro_monitor.py --log") | |
| sys.exit(1) | |
| log_file = log_files[0] | |
| print(f"📊 Анализ лога: {log_file.name}\n") | |
| analysis = analyze_memory_growth(log_file) | |
| recommendations = get_recommendations(analysis) | |
| print("=" * 80) | |
| print(" 🔍 РЕЗУЛЬТАТЫ АНАЛИЗА") | |
| print("=" * 80) | |
| print(f"\nВсего процессов: {analysis['total_processes']}") | |
| print(f"Обнаружено утечек: {len(analysis['leaks'])}\n") | |
| if recommendations: | |
| print("=" * 80) | |
| print(" 💡 РЕКОМЕНДАЦИИ") | |
| print("=" * 80) | |
| for i, rec in enumerate(recommendations, 1): | |
| print(f"\n{i}. {rec}\n") | |
| # Сохранить отчёт | |
| report_file = log_dir / f"kiro_analysis_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt" | |
| with open(report_file, 'w', encoding='utf-8') as f: | |
| f.write("KIRO PERFORMANCE ANALYSIS REPORT\n") | |
| f.write("=" * 80 + "\n\n") | |
| f.write(f"Log file: {log_file.name}\n") | |
| f.write(f"Total processes: {analysis['total_processes']}\n") | |
| f.write(f"Memory leaks detected: {len(analysis['leaks'])}\n\n") | |
| for i, rec in enumerate(recommendations, 1): | |
| f.write(f"{i}. {rec}\n\n") | |
| print(f"📝 Отчёт сохранён: {report_file}") | |
| if __name__ == "__main__": | |
| main() | |