buildstats: Improve to add getrusage data and corrected IO stats

Add IO stats and getrusage() data to the task statistics. We
also drop the CPU percentage calculation since its pretty arbitrary
and not very accurate/useful.

In particular we can now see the user and sys times as well as the
wall clock times.

(From OE-Core rev: b849130f71d3ba32a6fa94c291ca6ce7c7c3b3d1)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie 2015-12-17 14:54:28 +00:00
parent 3187647d89
commit adfdca4df1
1 changed files with 43 additions and 21 deletions

View File

@ -9,41 +9,53 @@ BUILDSTATS_BASE = "${TMPDIR}/buildstats/"
#
################################################################################
def get_process_cputime(pid):
def get_buildprocess_cputime(pid):
with open("/proc/%d/stat" % pid, "r") as f:
fields = f.readline().rstrip().split()
# 13: utime, 14: stime, 15: cutime, 16: cstime
return sum(int(field) for field in fields[13:16])
def get_process_cputime(pid):
import resource
with open("/proc/%d/stat" % pid, "r") as f:
fields = f.readline().rstrip().split()
stats = {
'utime' : fields[13],
'stime' : fields[14],
'cutime' : fields[15],
'cstime' : fields[16],
}
iostats = {}
with open("/proc/%d/io" % pid, "r") as f:
while True:
i = f.readline().strip()
if not i:
break
i = i.split(": ")
iostats[i[0]] = i[1]
resources = resource.getrusage(resource.RUSAGE_SELF)
childres = resource.getrusage(resource.RUSAGE_CHILDREN)
return stats, iostats, resources, childres
def get_cputime():
with open("/proc/stat", "r") as f:
fields = f.readline().rstrip().split()[1:]
return sum(int(field) for field in fields)
def set_timedata(var, d, server_time):
cputime = get_cputime()
proctime = get_process_cputime(os.getpid())
d.setVar(var, (server_time, cputime, proctime))
d.setVar(var, server_time)
def get_timedata(var, d, end_time):
timedata = d.getVar(var, False)
if timedata is None:
oldtime = d.getVar(var, False)
if oldtime is None:
return
oldtime, oldcpu, oldproc = timedata
procdiff = get_process_cputime(os.getpid()) - oldproc
cpudiff = get_cputime() - oldcpu
timediff = end_time - oldtime
if cpudiff > 0:
cpuperc = float(procdiff) * 100 / cpudiff
else:
cpuperc = None
return timediff, cpuperc
return end_time - oldtime
def set_buildtimedata(var, d):
import time
time = time.time()
cputime = get_cputime()
proctime = get_process_cputime(os.getpid())
proctime = get_buildprocess_cputime(os.getpid())
d.setVar(var, (time, cputime, proctime))
def get_buildtimedata(var, d):
@ -52,7 +64,7 @@ def get_buildtimedata(var, d):
if timedata is None:
return
oldtime, oldcpu, oldproc = timedata
procdiff = get_process_cputime(os.getpid()) - oldproc
procdiff = get_buildprocess_cputime(os.getpid()) - oldproc
cpudiff = get_cputime() - oldcpu
end_time = time.time()
timediff = end_time - oldtime
@ -66,13 +78,23 @@ def write_task_data(status, logfile, e, d):
bn = d.getVar('BUILDNAME', True)
bsdir = os.path.join(d.getVar('BUILDSTATS_BASE', True), bn)
with open(os.path.join(logfile), "a") as f:
timedata = get_timedata("__timedata_task", d, e.time)
if timedata:
elapsedtime, cpu = timedata
elapsedtime = get_timedata("__timedata_task", d, e.time)
if elapsedtime:
f.write(d.expand("${PF}: %s: Elapsed time: %0.2f seconds \n" %
(e.task, elapsedtime)))
cpu, iostats, resources, childres = get_process_cputime(os.getpid())
if cpu:
f.write("CPU usage: %0.1f%% \n" % cpu)
f.write("utime: %s\n" % cpu['utime'])
f.write("stime: %s\n" % cpu['stime'])
f.write("cutime: %s\n" % cpu['cutime'])
f.write("cstime: %s\n" % cpu['cstime'])
for i in iostats:
f.write("IO %s: %s\n" % (i, iostats[i]))
rusages = ["ru_utime", "ru_stime", "ru_maxrss", "ru_minflt", "ru_majflt", "ru_inblock", "ru_oublock", "ru_nvcsw", "ru_nivcsw"]
for i in rusages:
f.write("rusage %s: %s\n" % (i, getattr(resources, i)))
for i in rusages:
f.write("Child rusage %s: %s\n" % (i, getattr(childres, i)))
if status is "passed":
f.write("Status: PASSED \n")
else: