report-error.bbclass 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. ERR_REPORT_DIR ?= "${LOG_DIR}/error-report"
  9. def errorreport_getdata(e):
  10. import codecs
  11. logpath = e.data.getVar('ERR_REPORT_DIR')
  12. datafile = os.path.join(logpath, "error-report.txt")
  13. with codecs.open(datafile, 'r', 'utf-8') as f:
  14. data = f.read()
  15. return data
  16. def errorreport_savedata(e, newdata, file):
  17. import json
  18. import codecs
  19. logpath = e.data.getVar('ERR_REPORT_DIR')
  20. datafile = os.path.join(logpath, file)
  21. with codecs.open(datafile, 'w', 'utf-8') as f:
  22. json.dump(newdata, f, indent=4, sort_keys=True)
  23. return datafile
  24. def get_conf_data(e, filename):
  25. builddir = e.data.getVar('TOPDIR')
  26. filepath = os.path.join(builddir, "conf", filename)
  27. jsonstring = ""
  28. if os.path.exists(filepath):
  29. with open(filepath, 'r') as f:
  30. for line in f.readlines():
  31. if line.startswith("#") or len(line.strip()) == 0:
  32. continue
  33. else:
  34. jsonstring=jsonstring + line
  35. return jsonstring
  36. python errorreport_handler () {
  37. import json
  38. import codecs
  39. def nativelsb():
  40. nativelsbstr = e.data.getVar("NATIVELSBSTRING")
  41. # provide a bit more host info in case of uninative build
  42. if e.data.getVar('UNINATIVE_URL') != 'unset':
  43. return '/'.join([nativelsbstr, lsb_distro_identifier(e.data)])
  44. return nativelsbstr
  45. logpath = e.data.getVar('ERR_REPORT_DIR')
  46. datafile = os.path.join(logpath, "error-report.txt")
  47. if isinstance(e, bb.event.BuildStarted):
  48. bb.utils.mkdirhier(logpath)
  49. data = {}
  50. machine = e.data.getVar("MACHINE")
  51. data['machine'] = machine
  52. data['build_sys'] = e.data.getVar("BUILD_SYS")
  53. data['nativelsb'] = nativelsb()
  54. data['distro'] = e.data.getVar("DISTRO")
  55. data['target_sys'] = e.data.getVar("TARGET_SYS")
  56. data['failures'] = []
  57. data['component'] = " ".join(e.getPkgs())
  58. data['branch_commit'] = str(base_detect_branch(e.data)) + ": " + str(base_detect_revision(e.data))
  59. data['local_conf'] = get_conf_data(e, 'local.conf')
  60. data['auto_conf'] = get_conf_data(e, 'auto.conf')
  61. lock = bb.utils.lockfile(datafile + '.lock')
  62. errorreport_savedata(e, data, "error-report.txt")
  63. bb.utils.unlockfile(lock)
  64. elif isinstance(e, bb.build.TaskFailed):
  65. task = e.task
  66. taskdata={}
  67. log = e.data.getVar('BB_LOGFILE')
  68. taskdata['package'] = e.data.expand("${PF}")
  69. taskdata['task'] = task
  70. if log:
  71. try:
  72. with codecs.open(log, encoding='utf-8') as logFile:
  73. logdata = logFile.read()
  74. # Replace host-specific paths so the logs are cleaner
  75. for d in ("TOPDIR", "TMPDIR"):
  76. s = e.data.getVar(d)
  77. if s:
  78. logdata = logdata.replace(s, d)
  79. except:
  80. logdata = "Unable to read log file"
  81. else:
  82. logdata = "No Log"
  83. # server will refuse failures longer than param specified in project.settings.py
  84. # MAX_UPLOAD_SIZE = "5242880"
  85. # use lower value, because 650 chars can be spent in task, package, version
  86. max_logdata_size = 5242000
  87. # upload last max_logdata_size characters
  88. if len(logdata) > max_logdata_size:
  89. logdata = "..." + logdata[-max_logdata_size:]
  90. taskdata['log'] = logdata
  91. lock = bb.utils.lockfile(datafile + '.lock')
  92. jsondata = json.loads(errorreport_getdata(e))
  93. jsondata['failures'].append(taskdata)
  94. errorreport_savedata(e, jsondata, "error-report.txt")
  95. bb.utils.unlockfile(lock)
  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. addhandler errorreport_handler
  108. errorreport_handler[eventmask] = "bb.event.BuildStarted bb.event.BuildCompleted bb.build.TaskFailed"