| #!/usr/bin/env python |
| # SPDX-License-Identifier: GPL-2.0-only |
| # |
| # 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 |
| # |
| |
| 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),) |
| |
| if __name__ == "__main__": |
| main() |