diff mbox series

[RFC,2/3] build: Attach a log catcher to tasks and save their records

Message ID 20261024-mathieu-debug-replay-v4-v1-2-3f7f52a3b8e6@bootlin.com
State New
Headers show
Series Preparatory work for sstate cache log replay | expand

Commit Message

Mathieu Dubois-Briand Oct. 24, 2026, 12:33 p.m. UTC
Every task gets a LogCatcher which records its warnings and errors during
execution. Right after the task body, and before the postfuncs, the
records are written to ${T}/logrecords.<task>.json. The sstate packaging
postfunc reads the current task's file to bundle the messages for replay
when the task is later restored from the sstate cache.

Writing the file before the postfuncs makes both the current task's own
record and the files of already finished dependency tasks readable from
the same place.

AI-Generated: Uses opencode (DeepSeek V4 Flash)
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
---
 lib/bb/build.py | 13 +++++++++++++
 1 file changed, 13 insertions(+)
diff mbox series

Patch

diff --git a/lib/bb/build.py b/lib/bb/build.py
index 8b49721d60f8..033e5b1c3f30 100644
--- a/lib/bb/build.py
+++ b/lib/bb/build.py
@@ -21,6 +21,7 @@  import time
 import re
 import stat
 import datetime
+import json
 import bb
 import bb.msg
 import bb.process
@@ -656,6 +657,11 @@  def _exec_task(fn, task, d, quieterr):
         except OSError:
            pass
 
+    # Task log records, for sstate log replay. Written right after the task
+    # body, before the postfuncs, so the sstate packaging postfunc can read them.
+    logrecords = os.path.join(tempdir, 'logrecords.{0}.json'.format(task))
+    bb.utils.remove(logrecords)
+
     prefuncs = localdata.getVarFlag(task, 'prefuncs', expand=True)
     postfuncs = localdata.getVarFlag(task, 'postfuncs', expand=True)
 
@@ -698,6 +704,9 @@  def _exec_task(fn, task, d, quieterr):
     errchk = ErrorCheckHandler()
     bblogger.addHandler(errchk)
 
+    tasklogcatcher = bb.utils.LogCatcher()
+    bblogger.addHandler(tasklogcatcher)
+
     localdata.setVar('BB_LOGFILE', logfn)
     localdata.setVar('BB_RUNTASK', task)
     localdata.setVar('BB_TASK_LOGGER', bblogger)
@@ -711,6 +720,9 @@  def _exec_task(fn, task, d, quieterr):
             for func in (prefuncs or '').split():
                 exec_func(func, localdata)
             exec_func(task, localdata)
+            if tasklogcatcher.records:
+                with open(logrecords, 'w') as f:
+                    json.dump(tasklogcatcher.records, f)
             for func in (postfuncs or '').split():
                 exec_func(func, localdata)
         finally:
@@ -720,6 +732,7 @@  def _exec_task(fn, task, d, quieterr):
             sys.stderr.flush()
 
             bblogger.removeHandler(handler)
+            bblogger.removeHandler(tasklogcatcher)
 
             # Restore the backup fds
             os.dup2(osi[0], osi[1])