blob: 28e67e178194191bb1b4c2f5b02bc727470e67b1 [file] [log] [blame]
Finn Behrensc25ce582020-11-23 15:15:33 +01001#!/usr/bin/env python
Thomas Gleixneracf14702019-06-01 10:08:52 +02002# SPDX-License-Identifier: GPL-2.0-only
Linus Torvalds1da177e2005-04-16 15:20:36 -07003#
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#
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
12import sys
13import string
14
15def usage():
Mike Paganof29b5f32013-10-09 10:36:42 -040016 print ("""usage: show_delta [<options>] <filename>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017
18This program parses the output from a set of printk message lines which
19have time data prefixed because the CONFIG_PRINTK_TIME option is set, or
20the kernel command line option "time" is specified. When run with no
21options, the time information is converted to show the time delta between
22each printk line and the next. When run with the '-b' option, all times
23are relative to a single (base) point in time.
24
25Options:
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
33ex: $ dmesg >timefile
34 $ show_delta -b NET4 timefile
35
36will show times relative to the line in the kernel output
37starting with "NET4".
Mike Paganof29b5f32013-10-09 10:36:42 -040038""")
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 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
44def 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
60last_time = 0.0
61def 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
80def 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:
Mike Paganof29b5f32013-10-09 10:36:42 -040097 print ("Problem opening file: %s" % filein)
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 sys.exit(1)
99
100 if base_str:
Mike Paganof29b5f32013-10-09 10:36:42 -0400101 print ('base= "%s"' % base_str)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 # 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:
Mike Paganof29b5f32013-10-09 10:36:42 -0400120 print ('Couldn\'t find line matching base pattern "%s"' % base_str)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 sys.exit(1)
122 else:
123 base_time = 0.0
124
125 for line in lines:
Mike Paganof29b5f32013-10-09 10:36:42 -0400126 print (convert_line(line, base_time),)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128main()