1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#!/usr/bin/python
# profile reporter
import sys, os, operator, string
from optparse import OptionParser
from glob import glob
from subprocess import Popen, PIPE
import tarfile
class GlobalVars:
def __init__(self):
pass
class MyWriter:
def __init__(self, stdout, filename):
self.stdout = stdout
self.logfile = file(filename, 'w')
def write(self, text):
self.stdout.write(text)
self.logfile.write(text)
def close(self):
self.stdout.close()
self.logfile.close()
def parse_options(opts):
""" parse cmd line opts """
parser = OptionParser()
parser.add_option("-f","--filename", dest="filename",
help="write report to FILENAME")
parser.add_option("-t", "--time", dest="rtime",
help="set minimum RUNTIME to report", action="store",
default=float(0.1), type="float")
parser.add_option("-i", "--input", dest="rpt_dir",
help="define directory of sosreport archives",
action="store", default=False)
GlobalVars.cmdlineopts, GlobalVars.cmdlineargs = parser.parse_args(opts)
if not GlobalVars.cmdlineopts.rpt_dir:
raise SystemExit("\nPlease make sure to specify --input FILES\n")
def uncompress_reports(fname):
""" uncompresses the sosreport """
p = Popen(["xz","-d", fname], stdout=PIPE, stdin=PIPE)
out, err = p.communicate()
if err:
print "Problem extracting %s" % (fname,)
return
def read_archive(fname):
""" reads tarfile archive and grabs the sosprofile.log fileobj """
tar = tarfile.open(os.path.abspath(fname), "r:")
for tarinfo in tar.getmembers():
if 'sosprofile.log' in tarinfo.name:
fobj = tar.extractfile(tarinfo)
buf = fobj.read()
tar.close()
return buf
def timeoutput(secs):
if secs > 60:
secs = round(secs) / 60
return (secs, 'm')
elif secs < 60:
return (secs, 's')
def sort_profile():
""" provide reports on sosreport profiling """
# uncompress reports from input files
for rpt in glob(GlobalVars.cmdlineopts.rpt_dir+"/*.xz"):
uncompress_reports(os.path.abspath(rpt))
GlobalVars.rpt_count = 0
GlobalVars.timecount = 0
GlobalVars.lrc = {}
for rpt in glob(GlobalVars.cmdlineopts.rpt_dir+"/*.tar"):
buf = read_archive(rpt)
time_sorts=[]
if not buf:
continue
for line in buf.split("\n"):
try:
cmd, rtime = line.split("time:")
try:
# cmds that span multiple lines still need time calculated
cmd = cmd.split(":")[1]
except IndexError:
cmd, rtime = line.split("time:")
time_sorts.append((cmd.strip(), rtime.strip()))
except ValueError:
continue
time_count = 0
b_val_count = 0
write_stats = open(rpt + ".profile_report", 'w')
write_stats.write(28 * ' ' + 'SOSreport Profile Report' + 27 * ' ' + "\n")
write_stats.write(79 * '.' + "\n")
for a,b in sorted(time_sorts, key=operator.itemgetter(1)):
b_val = float(b)
time_count += b_val
if b_val > float(GlobalVars.cmdlineopts.rtime):
b_val_count += b_val
write_stats.write("%-79s %s\n" % (a[:78], b))
if GlobalVars.lrc.has_key(a) and \
GlobalVars.lrc[a] < b_val:
GlobalVars.lrc[a] = b_val
else:
GlobalVars.lrc[a] = b_val
# Keep up with total run time for all reports
GlobalVars.timecount += time_count
# Write out totals per report
write_stats.write(79 * '.' + "\n")
write_stats.write("Totals:\n")
secs, fmt = timeoutput(b_val_count)
write_stats.write("cumulative > %s: \t%f%s\n" % (GlobalVars.cmdlineopts.rtime, secs, fmt))
secs, fmt = timeoutput(time_count)
write_stats.write("cumulative total:\t%f%s\n" % (secs,fmt))
write_stats.close()
# increment report count so we can get an average runtime
GlobalVars.rpt_count += 1
if __name__ == "__main__":
parse_options(sys.argv[1:])
if GlobalVars.cmdlineopts.filename:
writer = MyWriter(sys.stdout, GlobalVars.cmdlineopts.filename)
sys.stdout = writer
print "Building reports ..."
sort_profile()
print 79 * "-"
print "Total runtime for %d reports is %fs" % (round(GlobalVars.rpt_count, 2), GlobalVars.timecount)
print "Average total runtime of %d reports is %fs" % (round(GlobalVars.rpt_count, 2), GlobalVars.timecount / GlobalVars.rpt_count)
print 79 * "-"
print
print "Longest running commands > %s:" % (GlobalVars.cmdlineopts.rtime,)
print 79 * "-"
for cmd, rtime in sorted(GlobalVars.lrc.iteritems(), key=operator.itemgetter(1)):
print "%-75s %s" % (cmd[:69], rtime)
if GlobalVars.cmdlineopts.filename:
print 79 * "-"
print "Report log written to: %s" % (GlobalVars.cmdlineopts.filename,)
writer.close()
|