blob: 2f692fbbccbed49bafd694c8ba218dbe5e4e5e84 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
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#
Patrick Williams92b42cb2022-09-03 06:53:57 -05007# SPDX-License-Identifier: MIT
8#
Patrick Williamsc124f4f2015-09-15 14:41:29 -05009
10ERR_REPORT_DIR ?= "${LOG_DIR}/error-report"
11
12def errorreport_getdata(e):
Patrick Williamsf1e5d692016-03-30 15:21:19 -050013 import codecs
Brad Bishop6e60e8b2018-02-01 10:27:11 -050014 logpath = e.data.getVar('ERR_REPORT_DIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050015 datafile = os.path.join(logpath, "error-report.txt")
Patrick Williamsf1e5d692016-03-30 15:21:19 -050016 with codecs.open(datafile, 'r', 'utf-8') as f:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050017 data = f.read()
18 return data
19
20def errorreport_savedata(e, newdata, file):
21 import json
Patrick Williamsf1e5d692016-03-30 15:21:19 -050022 import codecs
Brad Bishop6e60e8b2018-02-01 10:27:11 -050023 logpath = e.data.getVar('ERR_REPORT_DIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050024 datafile = os.path.join(logpath, file)
Patrick Williamsf1e5d692016-03-30 15:21:19 -050025 with codecs.open(datafile, 'w', 'utf-8') as f:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050026 json.dump(newdata, f, indent=4, sort_keys=True)
27 return datafile
28
Brad Bishopa34c0302019-09-23 22:34:48 -040029def get_conf_data(e, filename):
30 builddir = e.data.getVar('TOPDIR')
31 filepath = os.path.join(builddir, "conf", filename)
32 jsonstring = ""
33 if os.path.exists(filepath):
34 with open(filepath, 'r') as f:
35 for line in f.readlines():
36 if line.startswith("#") or len(line.strip()) == 0:
37 continue
38 else:
39 jsonstring=jsonstring + line
40 return jsonstring
41
Patrick Williamsc124f4f2015-09-15 14:41:29 -050042python errorreport_handler () {
43 import json
Patrick Williamsf1e5d692016-03-30 15:21:19 -050044 import codecs
Patrick Williamsc124f4f2015-09-15 14:41:29 -050045
Brad Bishopd7bf8c12018-02-25 22:55:05 -050046 def nativelsb():
47 nativelsbstr = e.data.getVar("NATIVELSBSTRING")
48 # provide a bit more host info in case of uninative build
49 if e.data.getVar('UNINATIVE_URL') != 'unset':
50 return '/'.join([nativelsbstr, lsb_distro_identifier(e.data)])
51 return nativelsbstr
52
Brad Bishop6e60e8b2018-02-01 10:27:11 -050053 logpath = e.data.getVar('ERR_REPORT_DIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050054 datafile = os.path.join(logpath, "error-report.txt")
55
56 if isinstance(e, bb.event.BuildStarted):
57 bb.utils.mkdirhier(logpath)
58 data = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -050059 machine = e.data.getVar("MACHINE")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060 data['machine'] = machine
Brad Bishop6e60e8b2018-02-01 10:27:11 -050061 data['build_sys'] = e.data.getVar("BUILD_SYS")
Brad Bishopd7bf8c12018-02-25 22:55:05 -050062 data['nativelsb'] = nativelsb()
Brad Bishop6e60e8b2018-02-01 10:27:11 -050063 data['distro'] = e.data.getVar("DISTRO")
64 data['target_sys'] = e.data.getVar("TARGET_SYS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065 data['failures'] = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -060066 data['component'] = " ".join(e.getPkgs())
Andrew Geissler78b72792022-06-14 06:47:25 -050067 data['branch_commit'] = str(oe.buildcfg.detect_branch(e.data)) + ": " + str(oe.buildcfg.detect_revision(e.data))
Andrew Geissler90fd73c2021-03-05 15:25:55 -060068 data['bitbake_version'] = e.data.getVar("BB_VERSION")
69 data['layer_version'] = get_layers_branch_rev(e.data)
Brad Bishopa34c0302019-09-23 22:34:48 -040070 data['local_conf'] = get_conf_data(e, 'local.conf')
71 data['auto_conf'] = get_conf_data(e, 'auto.conf')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050072 lock = bb.utils.lockfile(datafile + '.lock')
73 errorreport_savedata(e, data, "error-report.txt")
74 bb.utils.unlockfile(lock)
75
76 elif isinstance(e, bb.build.TaskFailed):
77 task = e.task
78 taskdata={}
Brad Bishop6e60e8b2018-02-01 10:27:11 -050079 log = e.data.getVar('BB_LOGFILE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050080 taskdata['package'] = e.data.expand("${PF}")
81 taskdata['task'] = task
82 if log:
83 try:
Brad Bishop64c979e2019-11-04 13:55:29 -050084 with codecs.open(log, encoding='utf-8') as logFile:
85 logdata = logFile.read()
Patrick Williamsc0f7c042017-02-23 20:41:17 -060086 # Replace host-specific paths so the logs are cleaner
87 for d in ("TOPDIR", "TMPDIR"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050088 s = e.data.getVar(d)
Patrick Williamsc0f7c042017-02-23 20:41:17 -060089 if s:
90 logdata = logdata.replace(s, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050091 except:
92 logdata = "Unable to read log file"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050093 else:
94 logdata = "No Log"
95
96 # server will refuse failures longer than param specified in project.settings.py
97 # MAX_UPLOAD_SIZE = "5242880"
98 # use lower value, because 650 chars can be spent in task, package, version
99 max_logdata_size = 5242000
100 # upload last max_logdata_size characters
101 if len(logdata) > max_logdata_size:
102 logdata = "..." + logdata[-max_logdata_size:]
103 taskdata['log'] = logdata
104 lock = bb.utils.lockfile(datafile + '.lock')
105 jsondata = json.loads(errorreport_getdata(e))
106 jsondata['failures'].append(taskdata)
107 errorreport_savedata(e, jsondata, "error-report.txt")
108 bb.utils.unlockfile(lock)
109
110 elif isinstance(e, bb.event.BuildCompleted):
111 lock = bb.utils.lockfile(datafile + '.lock')
112 jsondata = json.loads(errorreport_getdata(e))
113 bb.utils.unlockfile(lock)
114 failures = jsondata['failures']
115 if(len(failures) > 0):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500116 filename = "error_report_" + e.data.getVar("BUILDNAME")+".txt"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500117 datafile = errorreport_savedata(e, jsondata, filename)
118 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))
119 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.")
120}
121
122addhandler errorreport_handler
123errorreport_handler[eventmask] = "bb.event.BuildStarted bb.event.BuildCompleted bb.build.TaskFailed"