xref: /kernel/linux/linux-6.6/scripts/show_delta (revision 62306a36)
162306a36Sopenharmony_ci#!/usr/bin/env python
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
362306a36Sopenharmony_ci#
462306a36Sopenharmony_ci# show_deltas: Read list of printk messages instrumented with
562306a36Sopenharmony_ci# time data, and format with time deltas.
662306a36Sopenharmony_ci#
762306a36Sopenharmony_ci# Also, you can show the times relative to a fixed point.
862306a36Sopenharmony_ci#
962306a36Sopenharmony_ci# Copyright 2003 Sony Corporation
1062306a36Sopenharmony_ci#
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ciimport sys
1362306a36Sopenharmony_ciimport string
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cidef usage():
1662306a36Sopenharmony_ci	print ("""usage: show_delta [<options>] <filename>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciThis program parses the output from a set of printk message lines which
1962306a36Sopenharmony_cihave time data prefixed because the CONFIG_PRINTK_TIME option is set, or
2062306a36Sopenharmony_cithe kernel command line option "time" is specified. When run with no
2162306a36Sopenharmony_cioptions, the time information is converted to show the time delta between
2262306a36Sopenharmony_cieach printk line and the next.  When run with the '-b' option, all times
2362306a36Sopenharmony_ciare relative to a single (base) point in time.
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciOptions:
2662306a36Sopenharmony_ci  -h            Show this usage help.
2762306a36Sopenharmony_ci  -b <base>	Specify a base for time references.
2862306a36Sopenharmony_ci		<base> can be a number or a string.
2962306a36Sopenharmony_ci		If it is a string, the first message line
3062306a36Sopenharmony_ci		which matches (at the beginning of the
3162306a36Sopenharmony_ci		line) is used as the time reference.
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ciex: $ dmesg >timefile
3462306a36Sopenharmony_ci    $ show_delta -b NET4 timefile
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciwill show times relative to the line in the kernel output
3762306a36Sopenharmony_cistarting with "NET4".
3862306a36Sopenharmony_ci""")
3962306a36Sopenharmony_ci	sys.exit(1)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci# returns a tuple containing the seconds and text for each message line
4262306a36Sopenharmony_ci# seconds is returned as a float
4362306a36Sopenharmony_ci# raise an exception if no timing data was found
4462306a36Sopenharmony_cidef get_time(line):
4562306a36Sopenharmony_ci	if line[0]!="[":
4662306a36Sopenharmony_ci		raise ValueError
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	# split on closing bracket
4962306a36Sopenharmony_ci	(time_str, rest) = string.split(line[1:],']',1)
5062306a36Sopenharmony_ci	time = string.atof(time_str)
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	#print "time=", time
5362306a36Sopenharmony_ci	return (time, rest)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci# average line looks like:
5762306a36Sopenharmony_ci# [    0.084282] VFS: Mounted root (romfs filesystem) readonly
5862306a36Sopenharmony_ci# time data is expressed in seconds.useconds,
5962306a36Sopenharmony_ci# convert_line adds a delta for each line
6062306a36Sopenharmony_cilast_time = 0.0
6162306a36Sopenharmony_cidef convert_line(line, base_time):
6262306a36Sopenharmony_ci	global last_time
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	try:
6562306a36Sopenharmony_ci		(time, rest) = get_time(line)
6662306a36Sopenharmony_ci	except:
6762306a36Sopenharmony_ci		# if any problem parsing time, don't convert anything
6862306a36Sopenharmony_ci		return line
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	if base_time:
7162306a36Sopenharmony_ci		# show time from base
7262306a36Sopenharmony_ci		delta = time - base_time
7362306a36Sopenharmony_ci	else:
7462306a36Sopenharmony_ci		# just show time from last line
7562306a36Sopenharmony_ci		delta = time - last_time
7662306a36Sopenharmony_ci		last_time = time
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	return ("[%5.6f < %5.6f >]" % (time, delta)) + rest
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cidef main():
8162306a36Sopenharmony_ci	base_str = ""
8262306a36Sopenharmony_ci	filein = ""
8362306a36Sopenharmony_ci	for arg in sys.argv[1:]:
8462306a36Sopenharmony_ci		if arg=="-b":
8562306a36Sopenharmony_ci			base_str = sys.argv[sys.argv.index("-b")+1]
8662306a36Sopenharmony_ci		elif arg=="-h":
8762306a36Sopenharmony_ci			usage()
8862306a36Sopenharmony_ci		else:
8962306a36Sopenharmony_ci			filein = arg
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	if not filein:
9262306a36Sopenharmony_ci		usage()
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	try:
9562306a36Sopenharmony_ci		lines = open(filein,"r").readlines()
9662306a36Sopenharmony_ci	except:
9762306a36Sopenharmony_ci		print ("Problem opening file: %s" % filein)
9862306a36Sopenharmony_ci		sys.exit(1)
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	if base_str:
10162306a36Sopenharmony_ci		print ('base= "%s"' % base_str)
10262306a36Sopenharmony_ci		# assume a numeric base.  If that fails, try searching
10362306a36Sopenharmony_ci		# for a matching line.
10462306a36Sopenharmony_ci		try:
10562306a36Sopenharmony_ci			base_time = float(base_str)
10662306a36Sopenharmony_ci		except:
10762306a36Sopenharmony_ci			# search for line matching <base> string
10862306a36Sopenharmony_ci			found = 0
10962306a36Sopenharmony_ci			for line in lines:
11062306a36Sopenharmony_ci				try:
11162306a36Sopenharmony_ci					(time, rest) = get_time(line)
11262306a36Sopenharmony_ci				except:
11362306a36Sopenharmony_ci					continue
11462306a36Sopenharmony_ci				if string.find(rest, base_str)==1:
11562306a36Sopenharmony_ci					base_time = time
11662306a36Sopenharmony_ci					found = 1
11762306a36Sopenharmony_ci					# stop at first match
11862306a36Sopenharmony_ci					break
11962306a36Sopenharmony_ci			if not found:
12062306a36Sopenharmony_ci				print ('Couldn\'t find line matching base pattern "%s"' % base_str)
12162306a36Sopenharmony_ci				sys.exit(1)
12262306a36Sopenharmony_ci	else:
12362306a36Sopenharmony_ci		base_time = 0.0
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	for line in lines:
12662306a36Sopenharmony_ci		print (convert_line(line, base_time),)
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cimain()
129