ubuntu-boot team mailing list archive
-
ubuntu-boot team
-
Mailing list archive
-
Message #00002
Interpreting udev logs
Attached is my script for parsing udev log files and interpreting
various bits of data from it. This can be used to debug problems, and
also consider boot performance.
Missing UEVENT:
These are things that udev did that have no corresponding kernel
event, in theory this should never happen, but it does from time to
time -- I assume it's simply a monitoring bug.
Shows the time since start that udev finished processing the event.
Missing UDEV:
This is most useful when dealing with bug reports, if something has a
UEVENT but no UDEV, then udev failed to process the event. This can
be due to OPTIONS+="last_rule", a broken GOTO="..." or a udev timeout
Shows the time since start that the kernel sent the event.
Events:
The events processed; shows the time since start that the kernel sent
the event, the time since start that udev finished processing the
event, and thus the time that the event took to process.
This is sorted, so the top ones are the most trivial, the bottom took
the longest - though this can be because udev was locked processing
other events (the first, usually)
Statistics can be found near the bottom of the output.
Scott
--
Scott James Remnant
scott@xxxxxxxxxxxxx
#!/usr/bin/env python
import os
import sys
import math
def main(args):
for filename in args:
uevents, udevs = parse(filename)
results = process(uevents, udevs)
min_time = lowest(results)
max_what = max(len(what) for what, uevent, udev in results)
missing_uevent = sorted([ (what, uevent, udev)
for what, uevent, udev in results
if uevent is None ],
key=lambda x: x[2]['time'])
if len(missing_uevent):
print "Missing UEVENT"
print "--------------"
print "%-*s %-8s" % (max_what, "WHAT", "UDEV")
for what, uevent, udev in missing_uevent:
print "%-*s %5.2f" % (max_what, what, udev['time'] - min_time, )
print
missing_udev = sorted([ (what, uevent, udev)
for what, uevent, udev in results
if udev is None ],
key=lambda x: x[1]['time'])
if len(missing_udev):
print "Missing UDEV"
print "--------------"
print "%-*s %-8s" % (max_what, "WHAT", "UEVENT")
for what, uevent, udev in missing_udev:
print "%-*s %5.2f" % (max_what, what, uevent['time'] - min_time, )
print
events = sorted([ (what, uevent, udev)
for what, uevent, udev in results
if uevent is not None and udev is not None ],
key=lambda x: (x[2]['time'] - x[1]['time'], x[2]['time'], x[1]['time'])
if len(events):
print "Events"
print "------"
print "%-*s %-8s %-8s %-8s" % (max_what, "WHAT", "UEVENT", "UDEV", "TIME")
occurences = {}
total_time = 0
for what, uevent, udev in events:
print "%-*s %5.2f %5.2f %5.2f" % (max_what, what,
uevent['time'] - min_time,
udev['time'] - min_time,
udev['time'] - uevent['time'],)
total_time += udev['time'] - uevent['time']
mode_time = "%5.2f" % (udev['time'] - uevent['time'], )
if mode_time not in occurences:
occurences[mode_time] = 0
occurences[mode_time] += 1
print
mean = total_time / len(events)
median_what, median_uevent, median_udev = events[len(events) // 2]
median = median_udev['time'] - median_uevent['time']
mode = sorted(occurences.items(), key=lambda x: x[-1])[-1][0]
print "MEAN %5.2f" % mean
print "MEDIAN %5.2f" % median
print "MODE %s" % mode
total_deviation = 0
for what, uevent, udev in events:
deviation = udev['time'] - uevent['time'] - mean
total_deviation += math.pow(deviation, 2)
std_deviation = math.sqrt(total_deviation / len(events))
print "STDDEV %5.2f" % std_deviation
def parse(filename):
uevents = {}
udevs = {}
event = None
f = open(filename, "r")
try:
for line in f:
if line.startswith("UEVENT"):
eventlist = uevents
elif line.startswith("UDEV"):
eventlist = udevs
elif not len(line.rstrip("\n")):
event = None
elif event:
event['env'] += line
else:
continue
try:
time_start = line.index("[")
time_end = line.index("]")
time = float(line[time_start+1:time_end])
what = line[time_end+1:].lstrip().rstrip("\n")
except:
continue
event = {
'what': what,
'time': time,
'env': [],
}
if what not in eventlist:
eventlist[what] = []
eventlist[what].append(event)
finally:
f.close()
return uevents, udevs
def process(uevents, udevs):
results = []
for what in uevents.keys():
for uevent in uevents[what]:
try:
udev = udevs[what].pop(0)
except IndexError:
udev = None
results.append(( what, uevent, udev ))
for what in udevs.keys():
for udev in udevs[what]:
results.append(( what, None, udev ))
results.sort(key=lambda x: x[1] and x[1]['time'] or None)
return results
def lowest(results):
min_uevent_time = min(uevent['time'] for what, uevent, udev in results
if uevent is not None)
min_udev_time = min(udev['time'] for what, uevent, udev in results
if udev is not None)
if min_udev_time is None:
return min_uevent_time
elif min_uevent_time is None:
return min_udev_time
else:
return min(min_uevent_time, min_udev_time)
if __name__ == "__main__":
main(sys.argv[1:])
Attachment:
signature.asc
Description: This is a digitally signed message part