diff options
| -rw-r--r-- | meta/classes/buildstats.bbclass | 156 |
1 files changed, 73 insertions, 83 deletions
diff --git a/meta/classes/buildstats.bbclass b/meta/classes/buildstats.bbclass index 54d9f72b1d..22ec571b88 100644 --- a/meta/classes/buildstats.bbclass +++ b/meta/classes/buildstats.bbclass | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | BUILDSTATS_BASE = "${TMPDIR}/buildstats/" | 1 | BUILDSTATS_BASE = "${TMPDIR}/buildstats/" |
| 2 | BNFILE = "${BUILDSTATS_BASE}/.buildname" | 2 | BUILDSTATS_BNFILE = "${BUILDSTATS_BASE}/.buildname" |
| 3 | DEVFILE = "${BUILDSTATS_BASE}/.device" | 3 | BUILDSTATS_DEVFILE = "${BUILDSTATS_BASE}/.device" |
| 4 | 4 | ||
| 5 | ################################################################################ | 5 | ################################################################################ |
| 6 | # Build statistics gathering. | 6 | # Build statistics gathering. |
| @@ -25,21 +25,22 @@ def get_cputime(): | |||
| 25 | def set_bn(e): | 25 | def set_bn(e): |
| 26 | bn = e.getPkgs()[0] + "-" + e.data.getVar('MACHINE', True) | 26 | bn = e.getPkgs()[0] + "-" + e.data.getVar('MACHINE', True) |
| 27 | try: | 27 | try: |
| 28 | os.remove(e.data.getVar('BNFILE', True)) | 28 | os.remove(e.data.getVar('BUILDSTATS_BNFILE', True)) |
| 29 | except: | 29 | except: |
| 30 | pass | 30 | pass |
| 31 | with open(e.data.getVar('BNFILE', True), "w") as f: | 31 | with open(e.data.getVar('BUILDSTATS_BNFILE', True), "w") as f: |
| 32 | f.write(os.path.join(bn, e.data.getVar('BUILDNAME', True))) | 32 | f.write(os.path.join(bn, e.data.getVar('BUILDNAME', True))) |
| 33 | 33 | ||
| 34 | def get_bn(e): | 34 | def get_bn(e): |
| 35 | with open(e.data.getVar('BNFILE', True)) as f: | 35 | with open(e.data.getVar('BUILDSTATS_BNFILE', True)) as f: |
| 36 | bn = f.readline() | 36 | bn = f.readline() |
| 37 | return bn | 37 | return bn |
| 38 | 38 | ||
| 39 | def set_device(e): | 39 | def set_device(e): |
| 40 | tmpdir = e.data.getVar('TMPDIR', True) | 40 | tmpdir = e.data.getVar('TMPDIR', True) |
| 41 | devfile = e.data.getVar('BUILDSTATS_DEVFILE', True) | ||
| 41 | try: | 42 | try: |
| 42 | os.remove(e.data.getVar('DEVFILE', True)) | 43 | os.remove(devfile) |
| 43 | except: | 44 | except: |
| 44 | pass | 45 | pass |
| 45 | ############################################################################ | 46 | ############################################################################ |
| @@ -69,14 +70,12 @@ def set_device(e): | |||
| 69 | rdev = line.split()[2] | 70 | rdev = line.split()[2] |
| 70 | except: | 71 | except: |
| 71 | pass | 72 | pass |
| 72 | file = open(e.data.getVar('DEVFILE', True), "w") | 73 | with open(devfile, "w") as f: |
| 73 | file.write(rdev) | 74 | f.write(rdev) |
| 74 | file.close() | ||
| 75 | 75 | ||
| 76 | def get_device(e): | 76 | def get_device(e): |
| 77 | file = open(e.data.getVar('DEVFILE', True)) | 77 | with open(e.data.getVar('BUILDSTATS_DEVFILE', True)) as f: |
| 78 | device = file.readline() | 78 | device = f.readline() |
| 79 | file.close() | ||
| 80 | return device | 79 | return device |
| 81 | 80 | ||
| 82 | def get_diskstats(dev): | 81 | def get_diskstats(dev): |
| @@ -141,34 +140,32 @@ def get_timedata(var, data, server_time=None): | |||
| 141 | def write_task_data(status, logfile, dev, e): | 140 | def write_task_data(status, logfile, dev, e): |
| 142 | bn = get_bn(e) | 141 | bn = get_bn(e) |
| 143 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) | 142 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) |
| 144 | taskdir = os.path.join(bsdir, e.data.expand("${PF}")) | 143 | with open(os.path.join(logfile), "a") as f: |
| 145 | file = open(os.path.join(logfile), "a") | 144 | timedata = get_timedata("__timedata_task", e.data, e.time) |
| 146 | timedata = get_timedata("__timedata_task", e.data, e.time) | 145 | if timedata: |
| 147 | if timedata: | 146 | elapsedtime, cpu = timedata |
| 148 | elapsedtime, cpu = timedata | 147 | f.write(bb.data.expand("${PF}: %s: Elapsed time: %0.2f seconds \n" % |
| 149 | file.write(bb.data.expand("${PF}: %s: Elapsed time: %0.2f seconds \n" % | 148 | (e.task, elapsedtime), e.data)) |
| 150 | (e.task, elapsedtime), e.data)) | 149 | if cpu: |
| 151 | if cpu: | 150 | f.write("CPU usage: %0.1f%% \n" % cpu) |
| 152 | file.write("CPU usage: %0.1f%% \n" % cpu) | 151 | ############################################################################ |
| 153 | ############################################################################ | 152 | # Here we gather up disk data. In an effort to avoid lying with stats |
| 154 | # Here we gather up disk data. In an effort to avoid lying with stats | 153 | # I do a bare minimum of analysis of collected data. |
| 155 | # I do a bare minimum of analysis of collected data. | 154 | # The simple fact is, doing disk io collection on a per process basis |
| 156 | # The simple fact is, doing disk io collection on a per process basis | 155 | # without effecting build time would be difficult. |
| 157 | # without effecting build time would be difficult. | 156 | # For the best information, running things with BB_TOTAL_THREADS = "1" |
| 158 | # For the best information, running things with BB_TOTAL_THREADS = "1" | 157 | # would return accurate per task results. |
| 159 | # would return accurate per task results. | 158 | ############################################################################ |
| 160 | ############################################################################ | 159 | if dev != "NoLogicalDevice": |
| 161 | if dev != "NoLogicalDevice": | 160 | diskdata = get_diskdata("__diskdata_task", dev, e.data) |
| 162 | diskdata = get_diskdata("__diskdata_task", dev, e.data) | 161 | if diskdata: |
| 163 | if diskdata: | 162 | for key in sorted(diskdata.iterkeys()): |
| 164 | for key in sorted(diskdata.iterkeys()): | 163 | f.write(key + ": " + diskdata[key] + "\n") |
| 165 | file.write(key + ": " + diskdata[key] + "\n") | 164 | if status is "passed": |
| 166 | if status is "passed": | 165 | f.write("Status: PASSED \n") |
| 167 | file.write("Status: PASSED \n") | 166 | else: |
| 168 | else: | 167 | f.write("Status: FAILED \n") |
| 169 | file.write("Status: FAILED \n") | 168 | f.write("Ended: %0.2f \n" % e.time) |
| 170 | file.write("Ended: %0.2f \n" % e.time) | ||
| 171 | file.close() | ||
| 172 | 169 | ||
| 173 | python run_buildstats () { | 170 | python run_buildstats () { |
| 174 | import bb.build | 171 | import bb.build |
| @@ -194,75 +191,69 @@ python run_buildstats () { | |||
| 194 | set_timedata("__timedata_build", e.data) | 191 | set_timedata("__timedata_build", e.data) |
| 195 | build_time = os.path.join(bsdir, "build_stats") | 192 | build_time = os.path.join(bsdir, "build_stats") |
| 196 | # write start of build into build_time | 193 | # write start of build into build_time |
| 197 | file = open(build_time,"a") | 194 | with open(build_time, "a") as f: |
| 198 | host_info = platform.uname() | 195 | host_info = platform.uname() |
| 199 | file.write("Host Info: ") | 196 | f.write("Host Info: ") |
| 200 | for x in host_info: | 197 | for x in host_info: |
| 201 | if x: | 198 | if x: |
| 202 | file.write(x + " ") | 199 | f.write(x + " ") |
| 203 | file.write("\n") | 200 | f.write("\n") |
| 204 | file.write("Build Started: %0.2f \n" % time.time()) | 201 | f.write("Build Started: %0.2f \n" % time.time()) |
| 205 | file.close() | ||
| 206 | 202 | ||
| 207 | elif isinstance(e, bb.event.BuildCompleted): | 203 | elif isinstance(e, bb.event.BuildCompleted): |
| 208 | bn = get_bn(e) | 204 | bn = get_bn(e) |
| 209 | device = get_device(e) | 205 | device = get_device(e) |
| 210 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) | 206 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) |
| 211 | taskdir = os.path.join(bsdir, e.data.expand("${PF}")) | ||
| 212 | build_time = os.path.join(bsdir, "build_stats") | 207 | build_time = os.path.join(bsdir, "build_stats") |
| 213 | file = open(build_time, "a") | 208 | with open(build_time, "a") as f: |
| 214 | ######################################################################## | 209 | ######################################################################## |
| 215 | # Write build statistics for the build | 210 | # Write build statistics for the build |
| 216 | ######################################################################## | 211 | ######################################################################## |
| 217 | timedata = get_timedata("__timedata_build", e.data) | 212 | timedata = get_timedata("__timedata_build", e.data) |
| 218 | if timedata: | 213 | if timedata: |
| 219 | time, cpu = timedata | 214 | time, cpu = timedata |
| 220 | # write end of build and cpu used into build_time | 215 | # write end of build and cpu used into build_time |
| 221 | file.write("Elapsed time: %0.2f seconds \n" % (time)) | 216 | f.write("Elapsed time: %0.2f seconds \n" % (time)) |
| 222 | if cpu: | 217 | if cpu: |
| 223 | file.write("CPU usage: %0.1f%% \n" % cpu) | 218 | f.write("CPU usage: %0.1f%% \n" % cpu) |
| 224 | if device != "NoLogicalDevice": | 219 | if device != "NoLogicalDevice": |
| 225 | diskio = get_diskdata("__diskdata_build", device, e.data) | 220 | diskio = get_diskdata("__diskdata_build", device, e.data) |
| 226 | if diskio: | 221 | if diskio: |
| 227 | for key in sorted(diskio.iterkeys()): | 222 | for key in sorted(diskio.iterkeys()): |
| 228 | file.write(key + ": " + diskio[key] + "\n") | 223 | f.write(key + ": " + diskio[key] + "\n") |
| 229 | file.close() | ||
| 230 | 224 | ||
| 231 | if isinstance(e, bb.build.TaskStarted): | 225 | if isinstance(e, bb.build.TaskStarted): |
| 232 | bn = get_bn(e) | 226 | bn = get_bn(e) |
| 233 | device = get_device(e) | 227 | device = get_device(e) |
| 234 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) | 228 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) |
| 235 | taskdir = os.path.join(bsdir, e.data.expand("${PF}")) | 229 | taskdir = os.path.join(bsdir, e.data.getVar('PF', True)) |
| 236 | if device != "NoLogicalDevice": | 230 | if device != "NoLogicalDevice": |
| 237 | set_diskdata("__diskdata_task", device, e.data) | 231 | set_diskdata("__diskdata_task", device, e.data) |
| 238 | set_timedata("__timedata_task", e.data, e.time) | 232 | set_timedata("__timedata_task", e.data, e.time) |
| 239 | bb.utils.mkdirhier(taskdir) | 233 | bb.utils.mkdirhier(taskdir) |
| 240 | # write into the task event file the name and start time | 234 | # write into the task event file the name and start time |
| 241 | file = open(os.path.join(taskdir, e.task), "a") | 235 | with open(os.path.join(taskdir, e.task), "a") as f: |
| 242 | file.write("Event: %s \n" % bb.event.getName(e)) | 236 | f.write("Event: %s \n" % bb.event.getName(e)) |
| 243 | file.write("Started: %0.2f \n" % e.time) | 237 | f.write("Started: %0.2f \n" % e.time) |
| 244 | file.close() | ||
| 245 | 238 | ||
| 246 | elif isinstance(e, bb.build.TaskSucceeded): | 239 | elif isinstance(e, bb.build.TaskSucceeded): |
| 247 | bn = get_bn(e) | 240 | bn = get_bn(e) |
| 248 | device = get_device(e) | 241 | device = get_device(e) |
| 249 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) | 242 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) |
| 250 | taskdir = os.path.join(bsdir, e.data.expand("${PF}")) | 243 | taskdir = os.path.join(bsdir, e.data.getVar('PF', True)) |
| 251 | write_task_data("passed", os.path.join(taskdir, e.task), device, e) | 244 | write_task_data("passed", os.path.join(taskdir, e.task), device, e) |
| 252 | if e.task == "do_rootfs": | 245 | if e.task == "do_rootfs": |
| 253 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) | ||
| 254 | bs = os.path.join(bsdir, "build_stats") | 246 | bs = os.path.join(bsdir, "build_stats") |
| 255 | file = open(bs,"a") | 247 | with open(bs, "a") as f: |
| 256 | rootfs = e.data.getVar('IMAGE_ROOTFS', True) | 248 | rootfs = e.data.getVar('IMAGE_ROOTFS', True) |
| 257 | rootfs_size = subprocess.Popen(["du", "-sh", rootfs], stdout=subprocess.PIPE).stdout.read() | 249 | rootfs_size = subprocess.Popen(["du", "-sh", rootfs], stdout=subprocess.PIPE).stdout.read() |
| 258 | file.write("Uncompressed Rootfs size: %s" % rootfs_size) | 250 | f.write("Uncompressed Rootfs size: %s" % rootfs_size) |
| 259 | file.close() | ||
| 260 | 251 | ||
| 261 | elif isinstance(e, bb.build.TaskFailed): | 252 | elif isinstance(e, bb.build.TaskFailed): |
| 262 | bn = get_bn(e) | 253 | bn = get_bn(e) |
| 263 | device = get_device(e) | 254 | device = get_device(e) |
| 264 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) | 255 | bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn) |
| 265 | taskdir = os.path.join(bsdir, e.data.expand("${PF}")) | 256 | taskdir = os.path.join(bsdir, e.data.getVar('PF', True)) |
| 266 | write_task_data("failed", os.path.join(taskdir, e.task), device, e) | 257 | write_task_data("failed", os.path.join(taskdir, e.task), device, e) |
| 267 | ######################################################################## | 258 | ######################################################################## |
| 268 | # Lets make things easier and tell people where the build failed in | 259 | # Lets make things easier and tell people where the build failed in |
| @@ -270,9 +261,8 @@ python run_buildstats () { | |||
| 270 | # matter what the status of the build actually is | 261 | # matter what the status of the build actually is |
| 271 | ######################################################################## | 262 | ######################################################################## |
| 272 | build_status = os.path.join(bsdir, "build_stats") | 263 | build_status = os.path.join(bsdir, "build_stats") |
| 273 | file = open(build_status,"a") | 264 | with open(build_status, "a") as f: |
| 274 | file.write(e.data.expand("Failed at: ${PF} at task: %s \n" % e.task)) | 265 | f.write(e.data.expand("Failed at: ${PF} at task: %s \n" % e.task)) |
| 275 | file.close() | ||
| 276 | } | 266 | } |
| 277 | 267 | ||
| 278 | addhandler run_buildstats | 268 | addhandler run_buildstats |
