1 #!/usr/bin/env python
2 # SPDX-License-Identifier: GPL-2.0-only
3 #
4 # show_deltas: Read list of printk messages instrumented with
5 # time data, and format with time deltas.
6 #
7 # Also, you can show the times relative to a fixed point.
8 #
9 # Copyright 2003 Sony Corporation
10 #
11 
12 import sys
13 import string
14 
15 def usage():
16 	print ("""usage: show_delta [<options>] <filename>
17 
18 This program parses the output from a set of printk message lines which
19 have time data prefixed because the CONFIG_PRINTK_TIME option is set, or
20 the kernel command line option "time" is specified. When run with no
21 options, the time information is converted to show the time delta between
22 each printk line and the next.  When run with the '-b' option, all times
23 are relative to a single (base) point in time.
24 
25 Options:
26   -h            Show this usage help.
27   -b <base>	Specify a base for time references.
28 		<base> can be a number or a string.
29 		If it is a string, the first message line
30 		which matches (at the beginning of the
31 		line) is used as the time reference.
32 
33 ex: $ dmesg >timefile
34     $ show_delta -b NET4 timefile
35 
36 will show times relative to the line in the kernel output
37 starting with "NET4".
38 """)
39 	sys.exit(1)
40 
41 # returns a tuple containing the seconds and text for each message line
42 # seconds is returned as a float
43 # raise an exception if no timing data was found
44 def get_time(line):
45 	if line[0]!="[":
46 		raise ValueError
47 
48 	# split on closing bracket
49 	(time_str, rest) = string.split(line[1:],']',1)
50 	time = string.atof(time_str)
51 
52 	#print "time=", time
53 	return (time, rest)
54 
55 
56 # average line looks like:
57 # [    0.084282] VFS: Mounted root (romfs filesystem) readonly
58 # time data is expressed in seconds.useconds,
59 # convert_line adds a delta for each line
60 last_time = 0.0
61 def convert_line(line, base_time):
62 	global last_time
63 
64 	try:
65 		(time, rest) = get_time(line)
66 	except:
67 		# if any problem parsing time, don't convert anything
68 		return line
69 
70 	if base_time:
71 		# show time from base
72 		delta = time - base_time
73 	else:
74 		# just show time from last line
75 		delta = time - last_time
76 		last_time = time
77 
78 	return ("[%5.6f < %5.6f >]" % (time, delta)) + rest
79 
80 def main():
81 	base_str = ""
82 	filein = ""
83 	for arg in sys.argv[1:]:
84 		if arg=="-b":
85 			base_str = sys.argv[sys.argv.index("-b")+1]
86 		elif arg=="-h":
87 			usage()
88 		else:
89 			filein = arg
90 
91 	if not filein:
92 		usage()
93 
94 	try:
95 		lines = open(filein,"r").readlines()
96 	except:
97 		print ("Problem opening file: %s" % filein)
98 		sys.exit(1)
99 
100 	if base_str:
101 		print ('base= "%s"' % base_str)
102 		# assume a numeric base.  If that fails, try searching
103 		# for a matching line.
104 		try:
105 			base_time = float(base_str)
106 		except:
107 			# search for line matching <base> string
108 			found = 0
109 			for line in lines:
110 				try:
111 					(time, rest) = get_time(line)
112 				except:
113 					continue
114 				if string.find(rest, base_str)==1:
115 					base_time = time
116 					found = 1
117 					# stop at first match
118 					break
119 			if not found:
120 				print ('Couldn\'t find line matching base pattern "%s"' % base_str)
121 				sys.exit(1)
122 	else:
123 		base_time = 0.0
124 
125 	for line in lines:
126 		print (convert_line(line, base_time),)
127 
128 if __name__ == "__main__":
129 	main()
130