]> git.ipfire.org Git - pbs.git/commitdiff
jobs: Add a function to tail logs
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 19 Oct 2022 14:57:06 +0000 (14:57 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 19 Oct 2022 14:57:06 +0000 (14:57 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/jobs.py
tests/build.py

index 4bde08b1727c6216727cae5f70808fe0d7994be1..be811bf7145860a895c97e9494810602bbc0363b 100644 (file)
@@ -376,7 +376,7 @@ class Job(base.DataObject):
        def log_digest_blake2s(self):
                return self.data.log_digest_blake2s
 
-       async def open_log(self, mode="r"):
+       async def open_log(self, mode="rb"):
                """
                        Opens the log file, and returns an open file handle
                """
@@ -397,6 +397,28 @@ class Job(base.DataObject):
                else:
                        return open(open, mode)
 
+       async def tail_log(self, limit):
+               """
+                       Tails the log file (i.e. returns the N last lines)
+               """
+               # Open the log file
+               with await self.open_log() as f:
+                       return await asyncio.to_thread(self._tail_log, f, limit)
+
+       def _tail_log(self, f, limit):
+               # Create a new queue
+               q = []
+
+               # Walk through each line of the log file
+               for line in f:
+                       q.append(line)
+
+                       # Truncate the queue to limit to always have up to the last "limit" lines
+                       del q[:-limit]
+
+               # Return all lines
+               return q
+
        async def _import_log(self, upload):
                # Create some destination path
                path = self.backend.path(
index 44dc381b1e68ff4317d3207de6f6863d6525426a..61e9c54357980fef9254046786423308af932f16 100755 (executable)
@@ -225,6 +225,15 @@ class BuildTestCase(test.TestCase):
                with await job.open_log() as f:
                        self.assertIsInstance(f, io.IOBase)
 
+               # Fetch the last 100 lines of the log
+               lines = await job.tail_log(100)
+
+               # Check if we received the correct type
+               self.assertIsInstance(lines, list)
+
+               # Check if the result had the correct length
+               self.assertEqual(len(lines), 100)
+
 
 
 if __name__ == "__main__":