summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Maat <tristan.maat@codethink.com>2017-07-31 16:32:45 +0100
committerTristan Maat <tristan.maat@codethink.co.uk>2017-09-28 11:30:50 +0100
commitbe20f4113dd2c0b67e6223f83c86b9490224584a (patch)
tree1a8307ad95279ba298f3a94406f8cb444478966d
parent5d5d388e9894c575ecc982caf78e957dab9875d2 (diff)
downloadbuildstream-be20f4113dd2c0b67e6223f83c86b9490224584a.tar.gz
widget.py: Replace tail with a python implementation
-rw-r--r--buildstream/_frontend/widget.py29
1 files changed, 23 insertions, 6 deletions
diff --git a/buildstream/_frontend/widget.py b/buildstream/_frontend/widget.py
index c04cdafb7..92c553ef1 100644
--- a/buildstream/_frontend/widget.py
+++ b/buildstream/_frontend/widget.py
@@ -23,7 +23,9 @@ import subprocess
import datetime
import pkg_resources
from collections import OrderedDict
+from contextlib import ExitStack
from ruamel import yaml
+from mmap import mmap
from .. import utils, _yaml
from ..plugin import _plugin_lookup
@@ -386,12 +388,27 @@ class LogLine(Widget):
return text
def read_last_lines(self, logfile):
- tail_command = utils.get_host_tool('tail')
-
- # Lets just expect this to always pass for now...
- output = subprocess.check_output([tail_command, '-n', str(self.log_lines), logfile])
- output = output.decode('UTF-8')
- return output.rstrip()
+ with ExitStack() as stack:
+ # mmap handles low-level memory details, allowing for
+ # faster searches
+ f = stack.enter_context(open(logfile, 'r+'))
+ log = stack.enter_context(mmap(f.fileno(), os.path.getsize(f.name)))
+
+ count = 0
+ end = log.size() - 1
+
+ while count < self.log_lines and end >= 0:
+ location = log.rfind(b'\n', 0, end)
+ count += 1
+
+ # If location is -1 (none found), this will print the
+ # first character despite the later +1
+ end = location
+
+ # end+1 since we do not want to print the first newline
+ # (consistent with `tail` behavior)
+ lines = log[end:].splitlines()
+ return '\n'.join([line.decode('utf-8') for line in lines]).rstrip()
#
# A message to be printed at program startup, indicating