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