#!/usr/bin/env python3 # # Copyright (C) 2023 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import gzip import json import os import sys from collections import defaultdict READ_DURATION = [ 'soong', 'kati build', 'ninja', 'total', ] class Trace: def __init__(self, trace_file): self.duration = dict() self._queue = defaultdict(list) self.target = os.path.splitext(os.path.basename(trace_file))[0] if not os.path.isfile(trace_file): return self._trace_file = gzip.open(trace_file, 'rt', encoding='utf-8') self._trace_data = json.load(self._trace_file) for t in self._trace_data: if 'ph' not in t: continue if t['ph'] == 'X': self.duration[t['name']] = t['dur'] continue if t['ph'] == 'B': self._queue[(t['pid'], t['pid'])].append((t['name'], t['ts'])) continue if t['ph'] == 'E': queue = self._queue[(t['pid'], t['pid'])] if not queue: raise Exception('pid:{}, tid:{} not started'.format(t['pid'], t['pid'])) name, ts = queue.pop() self.duration[name] = t['ts'] - ts continue def out_durations(self): out_str = self.target for name in READ_DURATION: if name not in self.duration: continue out_str = '{}, {}'.format(out_str, self.duration[name]) out_str += '\n' sys.stdout.write(out_str) def main(argv): trace = Trace(argv[1]) trace.out_durations() if __name__ == '__main__': main(sys.argv)