/ scrape.py
scrape.py
1 import argparse 2 import json 3 import logging 4 import os 5 import sys 6 import traceback 7 from pathlib import Path 8 from typing import Callable, Iterable, List, Union 9 10 from log_multi_analysis import get_folders 11 from src.analysis.metrics.config import ScrapeConfig 12 from src.analysis.metrics.libp2p.scrape import Nimlibp2pScrapeBuilder 13 from src.analysis.metrics.scrapper import Scrapper 14 from src.analysis.plotting.config import PlotConfigBuilder 15 from src.analysis.plotting.metrics_plotter import MetricsPlotter 16 17 logger = logging.getLogger(__name__) 18 19 20 def setup_logger(): 21 level = logging.INFO 22 logging.getLogger().setLevel(level) 23 stream_handler = logging.StreamHandler(sys.stdout) 24 stream_handler.setLevel(level) 25 logging.getLogger().addHandler(stream_handler) 26 27 28 def extract_exps( 29 folders: List[str | Path], filters: List[Callable[[dict], bool]] 30 ) -> Iterable[dict]: 31 for folder in folders: 32 try: 33 metadata_log_path = Path(folder) / "metadata.json" 34 logger.info(f"Events log path: {metadata_log_path}") 35 with open(metadata_log_path, "r", encoding="utf-8") as f: 36 exp = json.load(f) 37 if any(filter(exp) == False for filter in filters): 38 logger.warning( 39 f"Experiment filtered out. path: `{metadata_log_path}` metadata: `{exp}`" 40 ) 41 continue 42 yield exp 43 except Exception as e: 44 full_trace = traceback.format_exc() 45 logger.error(f"exception: {e}\n{full_trace}") 46 raise 47 48 49 def get_nimlibp2p_exps(folder: Union[str, Path]) -> Iterable[dict]: 50 experiment_class = "NimLibp2pExperiment" 51 52 def filter_by_class(exp) -> bool: 53 if exp["experiment"]["class"] != experiment_class: 54 return False 55 return True 56 57 filters = [] 58 if experiment_class: 59 filters.append(filter_by_class) 60 61 paths = [folder / path for path in get_folders(Path(folder), "metadata.json")] 62 for exp in extract_exps(paths, filters): 63 yield exp 64 65 66 def nimlibp2p_regression_scrape_and_plots(k8s_config: str): 67 folders = [ 68 # TODO: Put paths here. 69 ] 70 exps = [] 71 for folder in folders: 72 exps.extend(get_nimlibp2p_exps(folder)) 73 74 scrapes: ScrapeConfig = [] 75 dump_fmt = "test_results/libp2p/1.16.0" 76 if len(exps) > 1: 77 dump_fmt += "_run_{i}" 78 for i, exp in enumerate(exps): 79 config = ( 80 Nimlibp2pScrapeBuilder() 81 .with_exp(exp, extract_name=True) 82 .with_dump_location(dump_fmt.format(i=i)) 83 .with_libp2p_metrics() 84 .build() 85 ) 86 scrapes.append(config) 87 scrapper = Scrapper(k8s_config, config) 88 scrapper.query_and_dump_metrics() 89 90 # Data from previous reports. 91 base = Path(__file__).parent / "nimlibp2pdata" 92 old_data_folders = [ 93 Path(base) / sub 94 for sub in [ 95 "nimlibp2p-1.12.0-1KB", 96 "nimlibp2p-1.13.0-1KB", 97 "nimlibp2p-1.14.0-1KB", 98 "nimlibp2p-1.15.0-1KB", 99 "nimlibp2p-1.16.0-1KB", 100 ] 101 ] 102 103 muxers = ["yamux", "quic", "mplex"] 104 in_plot = ( 105 PlotConfigBuilder(name="in") 106 .with_metric("libp2p-in") 107 .with_folders(old_data_folders) 108 .with_include_files(muxers) 109 .with_data_from_scrapes(scrapes) 110 .build() 111 ) 112 out_plot = ( 113 PlotConfigBuilder(name="out") 114 .with_metric("libp2p-out") 115 .with_folders(old_data_folders) 116 .with_include_files(muxers) 117 .with_data_from_scrapes(scrapes) 118 .build() 119 ) 120 121 MetricsPlotter(configs=[in_plot, out_plot]).create_plots() 122 123 124 def default_kubeconfig_path() -> str: 125 return os.environ.get("KUBECONFIG", str(Path.home() / ".kube" / "config")) 126 127 128 def parse_args() -> argparse.Namespace: 129 parser = argparse.ArgumentParser() 130 parser.add_argument( 131 "--config", 132 default=default_kubeconfig_path(), 133 help="Path to kubeconfig file", 134 ) 135 return parser.parse_args() 136 137 138 def main(): 139 setup_logger() 140 params = parse_args() 141 nimlibp2p_regression_scrape_and_plots(params.config) 142 143 144 if __name__ == "__main__": 145 main()