From 41f53c88dff7c35231d1e004e420a87d807f2a90 Mon Sep 17 00:00:00 2001 From: Rob Watson Date: Tue, 5 Jul 2022 18:26:47 +0200 Subject: [PATCH] podWatcher: prefer bufio.Reader to Scanner This avoids "token too large" errors when scanning large lines, probably at the cost of some memory usage and/or allocations. --- logs/pod_watcher.go | 23 ++++++++++++++++------- logs/watcher_test.go | 1 + 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/logs/pod_watcher.go b/logs/pod_watcher.go index 75fa1c5..596b975 100644 --- a/logs/pod_watcher.go +++ b/logs/pod_watcher.go @@ -225,13 +225,22 @@ func copyLogStream(ctx context.Context, wg *sync.WaitGroup, client KubernetesCli errch := make(chan error, 1) go func() { defer close(errch) - scanner := bufio.NewScanner(logReader) - for scanner.Scan() { - logsLines <- "[" + stream.podName + "] " + scanner.Text() + nl - } - if err := scanner.Err(); err != nil { - errch <- newLogError(fmt.Errorf("error scanning logs: %v", err), stream) - return + r := bufio.NewReader(logReader) + for { + lineBytes, err := r.ReadBytes('\n') + line := string(lineBytes) + if len(line) > 0 && !strings.HasSuffix(line, "\n") { + line += "\n" + } + if len(line) > 0 { + logsLines <- "[" + stream.podName + "] " + line + } + if err != nil { + if err != io.EOF { + errch <- newLogError(fmt.Errorf("error reading logs: %v", err), stream) + } + return + } } }() diff --git a/logs/watcher_test.go b/logs/watcher_test.go index ad2492d..0f1177e 100644 --- a/logs/watcher_test.go +++ b/logs/watcher_test.go @@ -164,6 +164,7 @@ func TestWatcherWithPodWatcher(t *testing.T) { assert.ElementsMatch(t, []string{"[foo] fake logs", "[bar] fake logs"}, lines) } +// bufToLines splits the output buffer removing newline characters. func bufToLines(buf *bytes.Buffer) []string { return strings.Split(strings.TrimSpace(buf.String()), "\n") }