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])
