def analyze_stats(file_path, top_n=20): entries = [] with open(file_path, 'r') as f: for line in f: line = line.strip() if not line: continue try: # Split the line by comma and get path, count and size parts = line.strip().rsplit(',', 2) if len(parts) == 3: path, count, size_mb = parts entries.append({ 'path': path, 'count': int(count), 'size_mb': float(size_mb) }) except (ValueError, IndexError) as e: print(f"Warning: Could not parse line: {line}. Error: {e}") # Sort by size in descending order entries.sort(key=lambda x: x['size_mb'], reverse=True) # Calculate totals total_files = sum(e['count'] for e in entries) total_size_mb = sum(e['size_mb'] for e in entries) total_size_gb = total_size_mb / 1024 total_size_tb = total_size_gb / 1024 print(f"\n=== Overall Statistics ===") print(f"Total directories: {len(entries):,}") print(f"Total files: {total_files:,}") print(f"Total size: {total_size_mb:,.2f} MB ({total_size_gb:,.2f} GB, {total_size_tb:,.2f} TB)") print(f"\n=== Top {top_n} Largest Directories ===") print(f"{'Path':<80} | {'Files':>10} | {'Size (MB)':>15} | {'Size (GB)':>15} | {'% of Total':>10}") print("-" * 150) for entry in entries[:top_n]: pct = (entry['size_mb'] / total_size_mb) * 100 print(f"{entry['path'][:78]:<80} | {entry['count']:10,} | {entry['size_mb']:15,.2f} | {(entry['size_mb']/1024):15,.2f} | {pct:8.2f}%") # Group by directory prefix (first two levels) print("\n=== Size by Top-Level Directories ===") dirs = {} for entry in entries: parts = entry['path'].split('/') if len(parts) >= 2: top_dir = '/'.join(parts[:2]) + '/' if top_dir not in dirs: dirs[top_dir] = {'count': 0, 'size_mb': 0.0} dirs[top_dir]['count'] += entry['count'] dirs[top_dir]['size_mb'] += entry['size_mb'] sorted_dirs = sorted(dirs.items(), key=lambda x: x[1]['size_mb'], reverse=True) print(f"{'Directory':<40} | {'Files':>10} | {'Size (MB)':>15} | {'Size (GB)':>15} | {'% of Total':>10}") print("-" * 100) for dir_name, stats in sorted_dirs[:top_n]: size_gb = stats['size_mb'] / 1024 pct = (stats['size_mb'] / total_size_mb) * 100 print(f"{dir_name[:38]:<40} | {stats['count']:10,} | {stats['size_mb']:15,.2f} | {size_gb:15,.2f} | {pct:8.2f}%") # Group by first 4 parts of the path (e.g., 0/prod-devtier/us-east-1-f01/1379661944629184106/) print("\n=== Size by Cluster Directories ===") cluster_dirs = {} for entry in entries: parts = entry['path'].split('/') if len(parts) >= 5: # Need at least 4 parts plus empty string from trailing / cluster_key = '/'.join(parts[:4]) + '/' # Join first 4 parts if cluster_key not in cluster_dirs: cluster_dirs[cluster_key] = {'count': 0, 'size_mb': 0.0} cluster_dirs[cluster_key]['count'] += entry['count'] cluster_dirs[cluster_key]['size_mb'] += entry['size_mb'] # Sort and print cluster directory stats sorted_cluster_dirs = sorted(cluster_dirs.items(), key=lambda x: x[1]['size_mb'], reverse=True) print(f"{'Cluster Directory':<80} | {'Files':>10} | {'Size (MB)':>15} | {'Size (GB)':>15} | {'% of Total':>10}") print("-" * 150) for dir_name, stats in sorted_cluster_dirs[:top_n]: pct = (stats['size_mb'] / total_size_mb) * 100 print(f"{dir_name[:78]:<80} | {stats['count']:10,} | {stats['size_mb']:15,.2f} | {(stats['size_mb']/1024):15,.2f} | {pct:8.2f}%") print("\n=== Size by Type Directories ===") type_dirs = {} for entry in entries: parts = [p for p in entry['path'].split('/') if p] if len(parts) < 2: continue # Normalize cross-cluster type keys: # .../profiles/ -> profiles/ # .../regions/ -> regions/ # .../logs/{component}/ -> logs/{component}/ if parts[-1] == 'profiles': type_key = 'profiles/' elif parts[-1] == 'regions': type_key = 'regions/' elif len(parts) >= 2 and parts[-2] == 'logs': type_key = f"logs/{parts[-1]}/" else: type_key = '/'.join(parts[-2:]) + '/' if type_key not in type_dirs: type_dirs[type_key] = {'count': 0, 'size_mb': 0.0} type_dirs[type_key]['count'] += entry['count'] type_dirs[type_key]['size_mb'] += entry['size_mb'] # Sort and print type directory stats sorted_type_dirs = sorted(type_dirs.items(), key=lambda x: x[1]['size_mb'], reverse=True) print(f"{'Type Directory':<80} | {'Files':>10} | {'Size (MB)':>15} | {'Size (GB)':>15} | {'% of Total':>10}") print("-" * 150) for dir_name, stats in sorted_type_dirs[:top_n]: pct = (stats['size_mb'] / total_size_mb) * 100 if total_size_mb else 0.0 print(f"{dir_name[:78]:<80} | {stats['count']:10,} | {stats['size_mb']:15,.2f} | {(stats['size_mb']/1024):15,.2f} | {pct:8.2f}%") if __name__ == "__main__": import sys if len(sys.argv) != 2: print("Usage: python analyze_stats.py ") sys.exit(1) file_path = sys.argv[1] analyze_stats(file_path)