action: footprint tracking
Add action and scripts for footprint tracking.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
diff --git a/scripts/footprint/upload_data.py b/scripts/footprint/upload_data.py
new file mode 100755
index 0000000..0084656
--- /dev/null
+++ b/scripts/footprint/upload_data.py
@@ -0,0 +1,153 @@
+#!/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)
+
+ 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()