0001 #!/usr/bin/env python
0002 # SPDX-License-Identifier: GPL-2.0-only
0003 #
0004 # show_deltas: Read list of printk messages instrumented with
0005 # time data, and format with time deltas.
0006 #
0007 # Also, you can show the times relative to a fixed point.
0008 #
0009 # Copyright 2003 Sony Corporation
0010 #
0011
0012 import sys
0013 import string
0014
0015 def usage():
0016 print ("""usage: show_delta [<options>] <filename>
0017
0018 This program parses the output from a set of printk message lines which
0019 have time data prefixed because the CONFIG_PRINTK_TIME option is set, or
0020 the kernel command line option "time" is specified. When run with no
0021 options, the time information is converted to show the time delta between
0022 each printk line and the next. When run with the '-b' option, all times
0023 are relative to a single (base) point in time.
0024
0025 Options:
0026 -h Show this usage help.
0027 -b <base> Specify a base for time references.
0028 <base> can be a number or a string.
0029 If it is a string, the first message line
0030 which matches (at the beginning of the
0031 line) is used as the time reference.
0032
0033 ex: $ dmesg >timefile
0034 $ show_delta -b NET4 timefile
0035
0036 will show times relative to the line in the kernel output
0037 starting with "NET4".
0038 """)
0039 sys.exit(1)
0040
0041 # returns a tuple containing the seconds and text for each message line
0042 # seconds is returned as a float
0043 # raise an exception if no timing data was found
0044 def get_time(line):
0045 if line[0]!="[":
0046 raise ValueError
0047
0048 # split on closing bracket
0049 (time_str, rest) = string.split(line[1:],']',1)
0050 time = string.atof(time_str)
0051
0052 #print "time=", time
0053 return (time, rest)
0054
0055
0056 # average line looks like:
0057 # [ 0.084282] VFS: Mounted root (romfs filesystem) readonly
0058 # time data is expressed in seconds.useconds,
0059 # convert_line adds a delta for each line
0060 last_time = 0.0
0061 def convert_line(line, base_time):
0062 global last_time
0063
0064 try:
0065 (time, rest) = get_time(line)
0066 except:
0067 # if any problem parsing time, don't convert anything
0068 return line
0069
0070 if base_time:
0071 # show time from base
0072 delta = time - base_time
0073 else:
0074 # just show time from last line
0075 delta = time - last_time
0076 last_time = time
0077
0078 return ("[%5.6f < %5.6f >]" % (time, delta)) + rest
0079
0080 def main():
0081 base_str = ""
0082 filein = ""
0083 for arg in sys.argv[1:]:
0084 if arg=="-b":
0085 base_str = sys.argv[sys.argv.index("-b")+1]
0086 elif arg=="-h":
0087 usage()
0088 else:
0089 filein = arg
0090
0091 if not filein:
0092 usage()
0093
0094 try:
0095 lines = open(filein,"r").readlines()
0096 except:
0097 print ("Problem opening file: %s" % filein)
0098 sys.exit(1)
0099
0100 if base_str:
0101 print ('base= "%s"' % base_str)
0102 # assume a numeric base. If that fails, try searching
0103 # for a matching line.
0104 try:
0105 base_time = float(base_str)
0106 except:
0107 # search for line matching <base> string
0108 found = 0
0109 for line in lines:
0110 try:
0111 (time, rest) = get_time(line)
0112 except:
0113 continue
0114 if string.find(rest, base_str)==1:
0115 base_time = time
0116 found = 1
0117 # stop at first match
0118 break
0119 if not found:
0120 print ('Couldn\'t find line matching base pattern "%s"' % base_str)
0121 sys.exit(1)
0122 else:
0123 base_time = 0.0
0124
0125 for line in lines:
0126 print (convert_line(line, base_time),)
0127
0128 main()