From: Richard Purdie <richard.purdie@linuxfoundation.org>
To: openembedded-core <openembedded-core@lists.openembedded.org>,
"Flanagan, Elizabeth" <elizabeth.flanagan@intel.com>
Subject: [PATCH 5/7] buildstats: Improve to add getrusage data and corrected IO stats
Date: Thu, 17 Dec 2015 14:54:28 +0000 [thread overview]
Message-ID: <1450364068.13505.209.camel@linuxfoundation.org> (raw)
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.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
diff --git a/meta/classes/buildstats.bbclass b/meta/classes/buildstats.bbclass
index 71469e4..daf0b86 100644
--- a/meta/classes/buildstats.bbclass
+++ b/meta/classes/buildstats.bbclass
@@ -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:
reply other threads:[~2015-12-17 14:54 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1450364068.13505.209.camel@linuxfoundation.org \
--to=richard.purdie@linuxfoundation.org \
--cc=elizabeth.flanagan@intel.com \
--cc=openembedded-core@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.