From 8d1f09daa2467aeb0b30d48279ae92fc26624c80 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Tue, 23 May 2023 15:58:24 +0000 Subject: [PATCH] log-stream: Allow sending how many initial lines we want to receive Signed-off-by: Michael Tremer --- src/buildservice/logstreams.py | 13 +++++++++---- src/static/css/site.scss | 8 ++++++++ src/static/js/job-log-stream.js | 7 +++++-- src/templates/jobs/modules/log-stream.html | 4 ++-- src/web/jobs.py | 10 +++++++--- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/buildservice/logstreams.py b/src/buildservice/logstreams.py index 0f89c6a7..c957e2d0 100644 --- a/src/buildservice/logstreams.py +++ b/src/buildservice/logstreams.py @@ -51,7 +51,7 @@ class LogStreams(base.Object): except KeyError: return - async def join(self, job, consumer): + async def join(self, job, consumer, **kwargs): """ Joins the stream for the given job """ @@ -61,7 +61,7 @@ class LogStreams(base.Object): return # Join the stream - await stream.join(consumer) + await stream.join(consumer, **kwargs) return stream @@ -97,7 +97,7 @@ class LogStream(base.Object): for consumer in self.consumers: consumer.close() - async def join(self, consumer): + async def join(self, consumer, limit=None): """ Called when a consumer wants to receive the stream """ @@ -105,7 +105,12 @@ class LogStream(base.Object): self.consumers.append(consumer) # Send all messages in the buffer - for message in self.buffer: + for i, message in enumerate(self.buffer): + # Only sent up to limit messages + if limit and i >= limit: + break + + # Send the message await consumer.message(message) log.debug("%s has joined the stream for %s" % (consumer, self.job)) diff --git a/src/static/css/site.scss b/src/static/css/site.scss index e34dc18f..be121e8e 100644 --- a/src/static/css/site.scss +++ b/src/static/css/site.scss @@ -48,6 +48,9 @@ html, body { // Use the code font font-family: $family-code; + // Break loglines like a terminal would + overflow-wrap: break-word; + // Keep any whitespace white-space: pre; @@ -69,6 +72,11 @@ html, body { background-color: $danger; color: $danger-invert; } + + &.is-small { + font-size: $size-small; + text-overflow: ellipsis; + } } /* diff --git a/src/static/js/job-log-stream.js b/src/static/js/job-log-stream.js index 0d5e015b..94a20f8a 100644 --- a/src/static/js/job-log-stream.js +++ b/src/static/js/job-log-stream.js @@ -9,7 +9,10 @@ $(".jobs-log-stream").each(function() { const log = $(this); // Make the URL - const url = "wss://" + window.location.host + "/api/v1/jobs/" + uuid + "/log/stream"; + var url = "wss://" + window.location.host + "/api/v1/jobs/" + uuid + "/log/stream"; + + if (limit > 0) + url += "?limit=" + limit; // Try to connect to the stream const stream = new WebSocket(url); @@ -21,7 +24,7 @@ $(".jobs-log-stream").each(function() { console.log("Message from server: ", data); // If there is a limit, reduce the number of rows first - while (limit > 0 && log.children().length > limit) { + while (limit > 0 && log.children().length >= limit) { log.children().first().remove(); } diff --git a/src/templates/jobs/modules/log-stream.html b/src/templates/jobs/modules/log-stream.html index 36237426..6cb93f6a 100644 --- a/src/templates/jobs/modules/log-stream.html +++ b/src/templates/jobs/modules/log-stream.html @@ -1,2 +1,2 @@ - + diff --git a/src/web/jobs.py b/src/web/jobs.py index 5ccd6370..4e964a19 100644 --- a/src/web/jobs.py +++ b/src/web/jobs.py @@ -110,8 +110,11 @@ class APIv1LogStreamHandler(base.BackendMixin, tornado.websocket.WebSocketHandle if not job: raise tornado.web.HTTPError(404, "Could not find job %s" % uuid) + # How many messages should be initially sent? + limit = self.get_argument_int("limit", None) + # Join the stream - self.stream = await self.backend.logstreams.join(job, self) + self.stream = await self.backend.logstreams.join(job, self, limit=limit) if not self.stream: raise tornado.web.HTTPError(400, "Could not join stream for %s" % job) @@ -230,8 +233,9 @@ class ListModule(ui_modules.UIModule): class LogStreamModule(ui_modules.UIModule): - def render(self, job, limit=None): - return self.render_string("jobs/modules/log-stream.html", job=job, limit=limit) + def render(self, job, limit=None, small=False): + return self.render_string("jobs/modules/log-stream.html", + job=job, limit=limit, small=small) def javascript_files(self): return [ -- 2.47.2