| #!/usr/bin/python | |
| # | |
| # show_deltas: Read list of printk messages instrumented with | |
| # time data, and format with time deltas. | |
| # | |
| # Also, you can show the times relative to a fixed point. | |
| # | |
| # Copyright 2003 Sony Corporation | |
| # | |
| # GPL 2.0 applies. | |
| import sys | |
| import string | |
| def usage(): | |
| print ("""usage: show_delta [<options>] <filename> | |
| This program parses the output from a set of printk message lines which | |
| have time data prefixed because the CONFIG_PRINTK_TIME option is set, or | |
| the kernel command line option "time" is specified. When run with no | |
| options, the time information is converted to show the time delta between | |
| each printk line and the next. When run with the '-b' option, all times | |
| are relative to a single (base) point in time. | |
| Options: | |
| -h Show this usage help. | |
| -b <base> Specify a base for time references. | |
| <base> can be a number or a string. | |
| If it is a string, the first message line | |
| which matches (at the beginning of the | |
| line) is used as the time reference. | |
| ex: $ dmesg >timefile | |
| $ show_delta -b NET4 timefile | |
| will show times relative to the line in the kernel output | |
| starting with "NET4". | |
| """) | |
| sys.exit(1) | |
| # returns a tuple containing the seconds and text for each message line | |
| # seconds is returned as a float | |
| # raise an exception if no timing data was found | |
| def get_time(line): | |
| if line[0]!="[": | |
| raise ValueError | |
| # split on closing bracket | |
| (time_str, rest) = string.split(line[1:],']',1) | |
| time = string.atof(time_str) | |
| #print "time=", time | |
| return (time, rest) | |
| # average line looks like: | |
| # [ 0.084282] VFS: Mounted root (romfs filesystem) readonly | |
| # time data is expressed in seconds.useconds, | |
| # convert_line adds a delta for each line | |
| last_time = 0.0 | |
| def convert_line(line, base_time): | |
| global last_time | |
| try: | |
| (time, rest) = get_time(line) | |
| except: | |
| # if any problem parsing time, don't convert anything | |
| return line | |
| if base_time: | |
| # show time from base | |
| delta = time - base_time | |
| else: | |
| # just show time from last line | |
| delta = time - last_time | |
| last_time = time | |
| return ("[%5.6f < %5.6f >]" % (time, delta)) + rest | |
| def main(): | |
| base_str = "" | |
| filein = "" | |
| for arg in sys.argv[1:]: | |
| if arg=="-b": | |
| base_str = sys.argv[sys.argv.index("-b")+1] | |
| elif arg=="-h": | |
| usage() | |
| else: | |
| filein = arg | |
| if not filein: | |
| usage() | |
| try: | |
| lines = open(filein,"r").readlines() | |
| except: | |
| print ("Problem opening file: %s" % filein) | |
| sys.exit(1) | |
| if base_str: | |
| print ('base= "%s"' % base_str) | |
| # assume a numeric base. If that fails, try searching | |
| # for a matching line. | |
| try: | |
| base_time = float(base_str) | |
| except: | |
| # search for line matching <base> string | |
| found = 0 | |
| for line in lines: | |
| try: | |
| (time, rest) = get_time(line) | |
| except: | |
| continue | |
| if string.find(rest, base_str)==1: | |
| base_time = time | |
| found = 1 | |
| # stop at first match | |
| break | |
| if not found: | |
| print ('Couldn\'t find line matching base pattern "%s"' % base_str) | |
| sys.exit(1) | |
| else: | |
| base_time = 0.0 | |
| for line in lines: | |
| print (convert_line(line, base_time),) | |
| main() |