mirror of
https://git.yoctoproject.org/poky
synced 2026-05-31 12:49:46 +00:00
buildstats.bbclass: add functionality to collect build system stats
There are a number of timeout and hang defects where
it would be useful to collect statistics about what
is running on a build host when that condition occurs.
This adds functionality to collect build system stats
on a regular interval and/or on task failure. Both
features are disabled by default.
To enable logging on a regular interval, set:
BB_HEARTBEAT_EVENT = "<interval>"
BB_LOG_HOST_STAT_ON_INTERVAL = <boolean>
Logs are stored in ${BUILDSTATS_BASE}/<build_name>/host_stats
To enable logging on a task failure, set:
BB_LOG_HOST_STAT_ON_FAILURE = "<boolean>"
Logs are stored in ${BUILDSTATS_BASE}/<build_name>/build_stats
The list of commands, along with the desired options, need
to be specified in the BB_LOG_HOST_STAT_CMDS variable
delimited by ; as such:
BB_LOG_HOST_STAT_CMDS = "command1 ; command2 ;... ;"
(From OE-Core rev: edb7098e9e0a8978568a45057c1c3ad2c6cacd67)
Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
75c779b628
commit
d068fbcde2
@@ -104,14 +104,46 @@ def write_task_data(status, logfile, e, d):
|
|||||||
f.write("Status: FAILED \n")
|
f.write("Status: FAILED \n")
|
||||||
f.write("Ended: %0.2f \n" % e.time)
|
f.write("Ended: %0.2f \n" % e.time)
|
||||||
|
|
||||||
|
def write_host_data(logfile, e, d):
|
||||||
|
import subprocess, os, datetime
|
||||||
|
cmds = d.getVar('BB_LOG_HOST_STAT_CMDS')
|
||||||
|
if cmds is None:
|
||||||
|
d.setVar("BB_LOG_HOST_STAT_ON_INTERVAL", "0")
|
||||||
|
d.setVar("BB_LOG_HOST_STAT_ON_FAILURE", "0")
|
||||||
|
bb.warn("buildstats: Collecting host data failed. Set BB_LOG_HOST_STAT_CMDS=\"command1 ; command2 ; ... \" in conf\/local.conf\n")
|
||||||
|
return
|
||||||
|
path = d.getVar("PATH")
|
||||||
|
opath = d.getVar("BB_ORIGENV", False).getVar("PATH")
|
||||||
|
ospath = os.environ['PATH']
|
||||||
|
os.environ['PATH'] = path + ":" + opath + ":" + ospath
|
||||||
|
with open(logfile, "a") as f:
|
||||||
|
f.write("Event Time: %f\nDate: %s\n" % (e.time, datetime.datetime.now()))
|
||||||
|
for cmd in cmds.split(";"):
|
||||||
|
if len(cmd) == 0:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, timeout=1).decode('utf-8')
|
||||||
|
except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError) as err:
|
||||||
|
output = "Error running command: %s\n%s\n" % (cmd, err)
|
||||||
|
f.write("%s\n%s\n" % (cmd, output))
|
||||||
|
os.environ['PATH'] = ospath
|
||||||
|
|
||||||
python run_buildstats () {
|
python run_buildstats () {
|
||||||
import bb.build
|
import bb.build
|
||||||
import bb.event
|
import bb.event
|
||||||
import time, subprocess, platform
|
import time, subprocess, platform
|
||||||
|
|
||||||
bn = d.getVar('BUILDNAME')
|
bn = d.getVar('BUILDNAME')
|
||||||
bsdir = os.path.join(d.getVar('BUILDSTATS_BASE'), bn)
|
########################################################################
|
||||||
taskdir = os.path.join(bsdir, d.getVar('PF'))
|
# bitbake fires HeartbeatEvent even before a build has been
|
||||||
|
# triggered, causing BUILDNAME to be None
|
||||||
|
########################################################################
|
||||||
|
if bn is not None:
|
||||||
|
bsdir = os.path.join(d.getVar('BUILDSTATS_BASE'), bn)
|
||||||
|
taskdir = os.path.join(bsdir, d.getVar('PF'))
|
||||||
|
if isinstance(e, bb.event.HeartbeatEvent) and bb.utils.to_boolean(d.getVar("BB_LOG_HOST_STAT_ON_INTERVAL")):
|
||||||
|
bb.utils.mkdirhier(bsdir)
|
||||||
|
write_host_data(os.path.join(bsdir, "host_stats"), e, d)
|
||||||
|
|
||||||
if isinstance(e, bb.event.BuildStarted):
|
if isinstance(e, bb.event.BuildStarted):
|
||||||
########################################################################
|
########################################################################
|
||||||
@@ -186,10 +218,12 @@ python run_buildstats () {
|
|||||||
build_status = os.path.join(bsdir, "build_stats")
|
build_status = os.path.join(bsdir, "build_stats")
|
||||||
with open(build_status, "a") as f:
|
with open(build_status, "a") as f:
|
||||||
f.write(d.expand("Failed at: ${PF} at task: %s \n" % e.task))
|
f.write(d.expand("Failed at: ${PF} at task: %s \n" % e.task))
|
||||||
|
if bb.utils.to_boolean(d.getVar("BB_LOG_HOST_STAT_ON_FAILURE")):
|
||||||
|
write_host_data(build_status, e, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
addhandler run_buildstats
|
addhandler run_buildstats
|
||||||
run_buildstats[eventmask] = "bb.event.BuildStarted bb.event.BuildCompleted bb.build.TaskStarted bb.build.TaskSucceeded bb.build.TaskFailed"
|
run_buildstats[eventmask] = "bb.event.BuildStarted bb.event.BuildCompleted bb.event.HeartbeatEvent bb.build.TaskStarted bb.build.TaskSucceeded bb.build.TaskFailed"
|
||||||
|
|
||||||
python runqueue_stats () {
|
python runqueue_stats () {
|
||||||
import buildstats
|
import buildstats
|
||||||
|
|||||||
Reference in New Issue
Block a user