2
# Copyright (C) 2016 Canonical Ltd.
4
# Author: Ryan Harper <ryan.harper@canonical.com>
6
# Curtin is free software: you can redistribute it and/or modify it under
7
# the terms of the GNU Affero General Public License as published by the
8
# Free Software Foundation, either version 3 of the License, or (at your
9
# option) any later version.
11
# Curtin is distributed in the hope that it will be useful, but WITHOUT ANY
12
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
16
# You should have received a copy of the GNU Affero General Public License
17
# along with Curtin. If not, see <http://www.gnu.org/licenses/>.
27
"description": "executing late commands",
28
"event_type": "start",
30
"name": "cmd-install/stage-late"
32
"timestamp": 1461164249.1590767,
36
"description": "executing late commands",
37
"event_type": "finish",
39
"name": "cmd-install/stage-late",
42
"timestamp": 1461164249.1590767
57
formatting_help = " ".join(["{}: {}".format(k.replace('%', '%%'), v)
58
for k, v in format_key.items()])
61
def format_record(msg, event):
62
for i, j in format_key.items():
64
msg = msg.replace(i, "{%s}" % j)
65
return msg.format(**event)
68
def generate_records(j, blame_sort=False, print_format="%d seconds in %D"):
73
name = event.get('name')
74
if event['event_type'] == 'start':
75
timestamps[name] = {'start': event['timestamp']}
77
timestamps[name].update({'finish': event['timestamp']})
78
start = datetime.datetime.utcfromtimestamp(
79
timestamps[name]['start'])
80
end = datetime.datetime.utcfromtimestamp(
81
timestamps[name]['finish'])
83
total_time += delta.total_seconds()
84
event['delta'] = "{:08.5f}".format(delta.total_seconds())
85
records.append(format_record(print_format, event))
87
records.append(' ---\n%3.5f seconds total time' % total_time)
92
parser = argparse.ArgumentParser(
93
description='curtin-print-log - pretty print and sort curtin logs',
94
prog='curtin-print-log')
95
parser.add_argument('--blame', action='store_true',
98
help='sort events by total time.')
99
parser.add_argument('--format', action='store',
101
default='%d seconds in %D',
102
help='specify formatting of output. ' +
104
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
105
help='Path to log to parse. Use - for stdin')
107
opts = parser.parse_args(sys.argv[1:])
113
j = json.load(opts.infile)
114
except json.JSONDecodeError:
115
print("Input must be valid JSON")
118
records = generate_records(j, blame_sort=opts.blame_sort,
119
print_format=opts.print_format)
121
if opts.blame_sort is True:
122
summary = records[-1:]
123
records = sorted(records[:-1], reverse=True)
125
print("\n".join(records + summary))
128
if __name__ == '__main__':