1#!/usr/bin/env python3 2# Copyright (c) 2021 Intel Corporation 3# 4# SPDX-License-Identifier: Apache-2.0 5 6from anytree.importer import DictImporter 7from anytree import PreOrderIter 8from anytree.search import find 9importer = DictImporter() 10from datetime import datetime 11from dateutil.relativedelta import relativedelta 12import os 13import json 14from git import Repo 15from git.exc import BadName 16 17from influxdb import InfluxDBClient 18import glob 19import argparse 20from tabulate import tabulate 21 22TODAY = datetime.utcnow() 23two_mon_rel = relativedelta(months=4) 24 25influx_dsn = 'influxdb://localhost:8086/footprint_tracking' 26 27def create_event(data, board, feature, commit, current_time, typ, application): 28 footprint_data = [] 29 client = InfluxDBClient.from_dsn(influx_dsn) 30 client.create_database('footprint_tracking') 31 for d in data.keys(): 32 footprint_data.append({ 33 "measurement": d, 34 "tags": { 35 "board": board, 36 "commit": commit, 37 "application": application, 38 "type": typ, 39 "feature": feature 40 }, 41 "time": current_time, 42 "fields": { 43 "value": data[d] 44 } 45 }) 46 47 client.write_points(footprint_data, time_precision='s', database='footprint_tracking') 48 49 50def parse_args(): 51 global args 52 parser = argparse.ArgumentParser( 53 description=__doc__, 54 formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) 55 56 parser.add_argument("-d", "--data", help="Data Directory") 57 parser.add_argument("-y", "--dryrun", action="store_true", help="Dry run, do not upload to database") 58 parser.add_argument("-z", "--zephyr-base", help="Zephyr tree") 59 parser.add_argument("-f", "--file", help="JSON file with footprint data") 60 args = parser.parse_args() 61 62 63def parse_file(json_file): 64 65 with open(json_file, "r") as fp: 66 contents = json.load(fp) 67 root = importer.import_(contents['symbols']) 68 69 zr = find(root, lambda node: node.name == 'ZEPHYR_BASE') 70 ws = find(root, lambda node: node.name == 'WORKSPACE') 71 72 data = {} 73 if zr and ws: 74 trees = [zr, ws] 75 else: 76 trees = [root] 77 78 for node in PreOrderIter(root, maxlevel=2): 79 if node.name not in ['WORKSPACE', 'ZEPHYR_BASE']: 80 if node.name in ['Root', 'Symbols']: 81 data['all'] = node.size 82 else: 83 data[node.name] = node.size 84 85 for t in trees: 86 root = t.name 87 for node in PreOrderIter(t, maxlevel=2): 88 if node.name == root: 89 continue 90 comp = node.name 91 if comp in ['Root', 'Symbols']: 92 data['all'] = node.size 93 else: 94 data[comp] = node.size 95 96 return data 97 98def process_files(data_dir, zephyr_base, dry_run): 99 repo = Repo(zephyr_base) 100 101 for hash in os.listdir(f'{data_dir}'): 102 if not dry_run: 103 client = InfluxDBClient.from_dsn(influx_dsn) 104 result = client.query(f"select * from kernel where commit = '{hash}';") 105 if result: 106 print(f"Skipping {hash}...") 107 continue 108 print(f"Importing {hash}...") 109 for file in glob.glob(f"{args.data}/{hash}/**/*json", recursive=True): 110 file_data = file.split("/") 111 json_file = os.path.basename(file) 112 if 'ram' in json_file: 113 typ = 'ram' 114 else: 115 typ = 'rom' 116 commit = file_data[1] 117 app = file_data[2] 118 feature = file_data[3] 119 board = file_data[4] 120 121 data = parse_file(file) 122 123 try: 124 gitcommit = repo.commit(f'{commit}') 125 current_time = gitcommit.committed_datetime 126 except BadName: 127 cidx = commit.find('-g') + 2 128 gitcommit = repo.commit(f'{commit[cidx:]}') 129 current_time = gitcommit.committed_datetime 130 131 print(current_time) 132 133 if not dry_run: 134 create_event(data, board, feature, commit, current_time, typ, app) 135 136def main(): 137 parse_args() 138 139 if args.data and args.zephyr_base: 140 process_files(args.data, args.zephyr_base, args.dryrun) 141 142 if args.file: 143 data = parse_file(args.file) 144 items = [] 145 for component,value in data.items(): 146 items.append([component,value]) 147 148 table = tabulate(items, headers=['Component', 'Size'], tablefmt='orgtbl') 149 print(table) 150 151 152if __name__ == "__main__": 153 main() 154