1# 2# Collects debug information in order to create error report files. 3# 4# Copyright (C) 2013 Intel Corporation 5# Author: Andreea Brandusa Proca <andreea.b.proca@intel.com> 6# 7# Licensed under the MIT license, see COPYING.MIT for details 8 9ERR_REPORT_DIR ?= "${LOG_DIR}/error-report" 10 11def errorreport_getdata(e): 12 import codecs 13 logpath = e.data.getVar('ERR_REPORT_DIR') 14 datafile = os.path.join(logpath, "error-report.txt") 15 with codecs.open(datafile, 'r', 'utf-8') as f: 16 data = f.read() 17 return data 18 19def errorreport_savedata(e, newdata, file): 20 import json 21 import codecs 22 logpath = e.data.getVar('ERR_REPORT_DIR') 23 datafile = os.path.join(logpath, file) 24 with codecs.open(datafile, 'w', 'utf-8') as f: 25 json.dump(newdata, f, indent=4, sort_keys=True) 26 return datafile 27 28python errorreport_handler () { 29 import json 30 import codecs 31 32 def nativelsb(): 33 nativelsbstr = e.data.getVar("NATIVELSBSTRING") 34 # provide a bit more host info in case of uninative build 35 if e.data.getVar('UNINATIVE_URL') != 'unset': 36 return '/'.join([nativelsbstr, lsb_distro_identifier(e.data)]) 37 return nativelsbstr 38 39 logpath = e.data.getVar('ERR_REPORT_DIR') 40 datafile = os.path.join(logpath, "error-report.txt") 41 42 if isinstance(e, bb.event.BuildStarted): 43 bb.utils.mkdirhier(logpath) 44 data = {} 45 machine = e.data.getVar("MACHINE") 46 data['machine'] = machine 47 data['build_sys'] = e.data.getVar("BUILD_SYS") 48 data['nativelsb'] = nativelsb() 49 data['distro'] = e.data.getVar("DISTRO") 50 data['target_sys'] = e.data.getVar("TARGET_SYS") 51 data['failures'] = [] 52 data['component'] = " ".join(e.getPkgs()) 53 data['branch_commit'] = str(base_detect_branch(e.data)) + ": " + str(base_detect_revision(e.data)) 54 lock = bb.utils.lockfile(datafile + '.lock') 55 errorreport_savedata(e, data, "error-report.txt") 56 bb.utils.unlockfile(lock) 57 58 elif isinstance(e, bb.build.TaskFailed): 59 task = e.task 60 taskdata={} 61 log = e.data.getVar('BB_LOGFILE') 62 taskdata['package'] = e.data.expand("${PF}") 63 taskdata['task'] = task 64 if log: 65 try: 66 logFile = codecs.open(log, 'r', 'utf-8') 67 logdata = logFile.read() 68 69 # Replace host-specific paths so the logs are cleaner 70 for d in ("TOPDIR", "TMPDIR"): 71 s = e.data.getVar(d) 72 if s: 73 logdata = logdata.replace(s, d) 74 75 logFile.close() 76 except: 77 logdata = "Unable to read log file" 78 79 else: 80 logdata = "No Log" 81 82 # server will refuse failures longer than param specified in project.settings.py 83 # MAX_UPLOAD_SIZE = "5242880" 84 # use lower value, because 650 chars can be spent in task, package, version 85 max_logdata_size = 5242000 86 # upload last max_logdata_size characters 87 if len(logdata) > max_logdata_size: 88 logdata = "..." + logdata[-max_logdata_size:] 89 taskdata['log'] = logdata 90 lock = bb.utils.lockfile(datafile + '.lock') 91 jsondata = json.loads(errorreport_getdata(e)) 92 jsondata['failures'].append(taskdata) 93 errorreport_savedata(e, jsondata, "error-report.txt") 94 bb.utils.unlockfile(lock) 95 96 elif isinstance(e, bb.event.BuildCompleted): 97 lock = bb.utils.lockfile(datafile + '.lock') 98 jsondata = json.loads(errorreport_getdata(e)) 99 bb.utils.unlockfile(lock) 100 failures = jsondata['failures'] 101 if(len(failures) > 0): 102 filename = "error_report_" + e.data.getVar("BUILDNAME")+".txt" 103 datafile = errorreport_savedata(e, jsondata, filename) 104 bb.note("The errors for this build are stored in %s\nYou can send the errors to a reports server by running:\n send-error-report %s [-s server]" % (datafile, datafile)) 105 bb.note("The contents of these logs will be posted in public if you use the above command with the default server. Please ensure you remove any identifying or proprietary information when prompted before sending.") 106} 107 108addhandler errorreport_handler 109errorreport_handler[eventmask] = "bb.event.BuildStarted bb.event.BuildCompleted bb.build.TaskFailed" 110