Spaces:
Running
Running
| """ | |
| ディスク使用量監視ユーティリティ | |
| """ | |
| import os | |
| import time | |
| import logging | |
| from datetime import datetime | |
| from pathlib import Path | |
| from typing import Dict, Any, Optional | |
| from utils.cache_manager import CacheManager | |
| class DiskMonitor: | |
| """ディスク使用量を監視するクラス""" | |
| def __init__(self, warning_threshold: float = 85.0, critical_threshold: float = 90.0): | |
| """ | |
| ディスク監視を初期化 | |
| Args: | |
| warning_threshold: 警告閾値(%) | |
| critical_threshold: 危険閾値(%) | |
| """ | |
| self.warning_threshold = warning_threshold | |
| self.critical_threshold = critical_threshold | |
| self.cache_manager = CacheManager() | |
| self.logger = logging.getLogger(__name__) | |
| # 最後の警告時刻を記録(重複警告を防ぐため) | |
| self.last_warning_time = None | |
| self.last_critical_time = None | |
| def get_status(self) -> Dict[str, Any]: | |
| """ | |
| 現在のディスク使用状況を取得 | |
| Returns: | |
| ディスク使用状況の辞書 | |
| """ | |
| try: | |
| disk_usage = self.cache_manager.get_disk_usage() | |
| if "error" in disk_usage: | |
| return {"error": disk_usage["error"]} | |
| usage_percent = disk_usage["working_directory"]["usage_percent"] | |
| # 警告レベルを判定 | |
| if usage_percent >= self.critical_threshold: | |
| level = "CRITICAL" | |
| action_needed = "immediate_cleanup" | |
| elif usage_percent >= self.warning_threshold: | |
| level = "WARNING" | |
| action_needed = "cleanup_recommended" | |
| else: | |
| level = "OK" | |
| action_needed = "none" | |
| return { | |
| "level": level, | |
| "usage_percent": usage_percent, | |
| "action_needed": action_needed, | |
| "disk_usage": disk_usage, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| except Exception as e: | |
| self.logger.error(f"ディスク状況の取得に失敗: {e}") | |
| return {"error": str(e)} | |
| def check_and_alert(self) -> Optional[Dict[str, Any]]: | |
| """ | |
| ディスク使用量をチェックし、必要に応じて警告を発行 | |
| Returns: | |
| 警告が発行された場合の情報 | |
| """ | |
| try: | |
| status = self.get_status() | |
| if "error" in status: | |
| return None | |
| current_time = time.time() | |
| usage_percent = status["usage_percent"] | |
| # 危険レベルの処理 | |
| if usage_percent >= self.critical_threshold: | |
| # 前回の警告から1時間以上経過している場合のみ警告 | |
| if (self.last_critical_time is None or | |
| current_time - self.last_critical_time > 3600): | |
| self.last_critical_time = current_time | |
| # 緊急クリーンアップを実行 | |
| cleanup_result = self.cache_manager.emergency_cleanup() | |
| alert_message = { | |
| "level": "CRITICAL", | |
| "message": f"ディスク使用率が危険レベルに達しました: {usage_percent:.1f}%", | |
| "action_taken": "emergency_cleanup", | |
| "cleanup_result": cleanup_result, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| self.logger.critical(alert_message["message"]) | |
| print(f"[CRITICAL] {alert_message['message']}") | |
| return alert_message | |
| # 警告レベルの処理 | |
| elif usage_percent >= self.warning_threshold: | |
| # 前回の警告から30分以上経過している場合のみ警告 | |
| if (self.last_warning_time is None or | |
| current_time - self.last_warning_time > 1800): | |
| self.last_warning_time = current_time | |
| # 通常のクリーンアップを実行 | |
| cleanup_result = self.cache_manager.cleanup_cache() | |
| alert_message = { | |
| "level": "WARNING", | |
| "message": f"ディスク使用率が警告レベルに達しました: {usage_percent:.1f}%", | |
| "action_taken": "cleanup", | |
| "cleanup_result": cleanup_result, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| self.logger.warning(alert_message["message"]) | |
| print(f"[WARNING] {alert_message['message']}") | |
| return alert_message | |
| return None | |
| except Exception as e: | |
| self.logger.error(f"ディスク監視でエラーが発生: {e}") | |
| return None | |
| def continuous_monitor(self, interval: int = 300): | |
| """ | |
| 継続的にディスク使用量を監視 | |
| Args: | |
| interval: 監視間隔(秒) | |
| """ | |
| print(f"[INFO] ディスク監視を開始しました(間隔: {interval}秒)") | |
| try: | |
| while True: | |
| alert = self.check_and_alert() | |
| if alert: | |
| print(f"[ALERT] {alert['message']}") | |
| time.sleep(interval) | |
| except KeyboardInterrupt: | |
| print("[INFO] ディスク監視を停止しました") | |
| except Exception as e: | |
| self.logger.error(f"ディスク監視中にエラーが発生: {e}") | |
| print(f"[ERROR] ディスク監視中にエラーが発生: {e}") | |
| def generate_report(self) -> str: | |
| """ | |
| 現在の状況レポートを生成 | |
| Returns: | |
| レポート文字列 | |
| """ | |
| try: | |
| status = self.get_status() | |
| if "error" in status: | |
| return f"レポート生成エラー: {status['error']}" | |
| disk_usage = status["disk_usage"] | |
| working_dir = disk_usage["working_directory"] | |
| cache_info = disk_usage["cache"] | |
| report = f""" | |
| === ディスク使用量レポート === | |
| 生成日時: {status['timestamp']} | |
| 警告レベル: {status['level']} | |
| 【作業用ディレクトリ】 | |
| パス: {working_dir['path']} | |
| 使用率: {working_dir['usage_percent']:.1f}% | |
| 使用量: {working_dir['used_gb']:.2f}GB / {working_dir['total_gb']:.2f}GB | |
| 空き容量: {working_dir['free_gb']:.2f}GB | |
| 【Huggingfaceキャッシュ】 | |
| キャッシュサイズ: {cache_info.get('total_size_gb', 0):.2f}GB | |
| リポジトリ数: {cache_info.get('num_repos', 0)} | |
| キャッシュパス: {cache_info.get('cache_path', 'N/A')} | |
| 【推奨アクション】 | |
| """ | |
| if status["action_needed"] == "immediate_cleanup": | |
| report += "⚠️ 緊急: 即座にキャッシュクリーンアップが必要です" | |
| elif status["action_needed"] == "cleanup_recommended": | |
| report += "⚠️ 推奨: キャッシュクリーンアップを検討してください" | |
| else: | |
| report += "✅ 現在のところ、アクションは不要です" | |
| return report | |
| except Exception as e: | |
| return f"レポート生成中にエラーが発生: {e}" | |
| def main(): | |
| """メイン関数(スタンドアロン実行用)""" | |
| import argparse | |
| parser = argparse.ArgumentParser(description="ディスク使用量監視ツール") | |
| parser.add_argument("--monitor", action="store_true", help="継続監視を開始") | |
| parser.add_argument("--report", action="store_true", help="現在の状況レポートを表示") | |
| parser.add_argument("--interval", type=int, default=300, help="監視間隔(秒)") | |
| parser.add_argument("--warning", type=float, default=85.0, help="警告閾値(%)") | |
| parser.add_argument("--critical", type=float, default=90.0, help="危険閾値(%)") | |
| args = parser.parse_args() | |
| monitor = DiskMonitor( | |
| warning_threshold=args.warning, | |
| critical_threshold=args.critical | |
| ) | |
| if args.monitor: | |
| monitor.continuous_monitor(interval=args.interval) | |
| elif args.report: | |
| print(monitor.generate_report()) | |
| else: | |
| # デフォルト: 1回だけチェック | |
| status = monitor.get_status() | |
| if "error" in status: | |
| print(f"エラー: {status['error']}") | |
| else: | |
| print(f"ディスク使用率: {status['usage_percent']:.1f}% ({status['level']})") | |
| alert = monitor.check_and_alert() | |
| if alert: | |
| print(f"警告: {alert['message']}") | |
| if __name__ == "__main__": | |
| main() |