#!/usr/bin/env python3 # Copyright (c) 2021 Intel Corporation # # SPDX-License-Identifier: Apache-2.0 from anytree.importer import DictImporter from anytree import PreOrderIter from anytree.search import find importer = DictImporter() from datetime import datetime from dateutil.relativedelta import relativedelta import os import json from git import Repo from git.exc import BadName from influxdb import InfluxDBClient import glob import argparse from tabulate import tabulate TODAY = datetime.utcnow() two_mon_rel = relativedelta(months=4) influx_dsn = 'influxdb://localhost:8086/footprint_tracking' def create_event(data, board, feature, commit, current_time, typ, application): footprint_data = [] client = InfluxDBClient.from_dsn(influx_dsn) client.create_database('footprint_tracking') for d in data.keys(): footprint_data.append({ "measurement": d, "tags": { "board": board, "commit": commit, "application": application, "type": typ, "feature": feature }, "time": current_time, "fields": { "value": data[d] } }) client.write_points(footprint_data, time_precision='s', database='footprint_tracking') def parse_args(): global args parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) parser.add_argument("-d", "--data", help="Data Directory") parser.add_argument("-y", "--dryrun", action="store_true", help="Dry run, do not upload to database") parser.add_argument("-z", "--zephyr-base", help="Zephyr tree") parser.add_argument("-f", "--file", help="JSON file with footprint data") args = parser.parse_args() def parse_file(json_file): with open(json_file, "r") as fp: contents = json.load(fp) root = importer.import_(contents['symbols']) zr = find(root, lambda node: node.name == 'ZEPHYR_BASE') ws = find(root, lambda node: node.name == 'WORKSPACE') data = {} if zr and ws: trees = [zr, ws] else: trees = [root] for node in PreOrderIter(root, maxlevel=2): if node.name not in ['WORKSPACE', 'ZEPHYR_BASE']: if node.name in ['Root', 'Symbols']: data['all'] = node.size else: data[node.name] = node.size for t in trees: root = t.name for node in PreOrderIter(t, maxlevel=2): if node.name == root: continue comp = node.name if comp in ['Root', 'Symbols']: data['all'] = node.size else: data[comp] = node.size return data def process_files(data_dir, zephyr_base, dry_run): repo = Repo(zephyr_base) for hash in os.listdir(f'{data_dir}'): if not dry_run: client = InfluxDBClient.from_dsn(influx_dsn) result = client.query(f"select * from kernel where commit = '{hash}';") if result: print(f"Skipping {hash}...") continue print(f"Importing {hash}...") for file in glob.glob(f"{args.data}/{hash}/**/*json", recursive=True): file_data = file.split("/") json_file = os.path.basename(file) if 'ram' in json_file: typ = 'ram' else: typ = 'rom' commit = file_data[1] app = file_data[2] feature = file_data[3] board = file_data[4] data = parse_file(file) try: gitcommit = repo.commit(f'{commit}') current_time = gitcommit.committed_datetime except BadName: cidx = commit.find('-g') + 2 gitcommit = repo.commit(f'{commit[cidx:]}') current_time = gitcommit.committed_datetime print(current_time) if not dry_run: create_event(data, board, feature, commit, current_time, typ, app) def main(): parse_args() if args.data and args.zephyr_base: process_files(args.data, args.zephyr_base, args.dryrun) if args.file: data = parse_file(args.file) items = [] for component,value in data.items(): items.append([component,value]) table = tabulate(items, headers=['Component', 'Size'], tablefmt='orgtbl') print(table) if __name__ == "__main__": main()