| # Copyright 2021 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """ |
| This scripts allows to get basic stats about the inspect.json file contained in a snapshot.zip file. |
| |
| To use you need to have a snapshot.zip file either generated by `ffx inspect` or from a crash report. |
| |
| Example usage: |
| |
| ``` |
| $ unzip /path/to/snapshot.zip |
| $ fuchsia-vendored-python snapshot_inspect_stats.py --sort nodes /path/to/unzipped/inspect.json |
| ``` |
| """ |
| |
| import argparse |
| import json |
| import sys |
| |
| |
| def measure(obj: dict[str, object], depth: int = 0) -> tuple[int, int, int]: |
| """ |
| Returns the number of nodes, properties and the depth of an inspect tree. |
| `obj` is a dict read from JSON that represents inspect data |
| """ |
| nodes = 0 |
| properties = 0 |
| max_depth = depth |
| for _, child in obj.items(): |
| # ensure this is a node that is not a histogram |
| if type(child) is dict and "buckets" not in child: |
| (child_nodes, child_properties, child_depth) = measure( |
| child, depth=depth + 1 |
| ) |
| nodes += child_nodes + 1 |
| properties += child_properties |
| max_depth = max(max_depth, child_depth) |
| continue |
| properties += 1 |
| return nodes, properties, max_depth |
| |
| |
| def get_sort_index(sort_opt: str) -> int: |
| if args.sort == "nodes": |
| return 0 |
| elif args.sort == "properties": |
| return 1 |
| elif args.sort == "depth": |
| return 2 |
| return -1 |
| |
| |
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser( |
| description="Show stats about inspect data in a snapshot." |
| ) |
| parser.add_argument( |
| "filepath", metavar="FILE", type=str, help="path to inspect.json file" |
| ) |
| parser.add_argument( |
| "--sort", |
| dest="sort", |
| choices=["depth", "nodes", "properties"], |
| default="nodes", |
| help="based on what the output will be sorted", |
| ) |
| |
| args = parser.parse_args(sys.argv[1:]) |
| |
| with open(args.filepath) as f: |
| data = json.load(f) |
| results = [ |
| (response["moniker"], measure(response["payload"])) |
| for response in data |
| if response["payload"] |
| ] |
| sort_index = get_sort_index(args.sort) |
| results.sort(key=lambda v: v[1][sort_index], reverse=True) |
| print("MONIKER NODES PROPERTIES DEPTH") |
| for moniker, (nodes, properties, depth) in results: |
| print("{:<20} {} {} {}".format(moniker, nodes, properties, depth)) |