Skip to content

Fix handling of partial log lines#290

Merged
jasonopslevel merged 1 commit intomainfrom
ehuus/fix-partial-log-lines
Apr 22, 2026
Merged

Fix handling of partial log lines#290
jasonopslevel merged 1 commit intomainfrom
ehuus/fix-partial-log-lines

Conversation

@eapache-opslevel
Copy link
Copy Markdown
Contributor

@eapache-opslevel eapache-opslevel commented Apr 21, 2026

The k8s stdout/stderr streamer is byte oriented and does not particularly care about newline boundaries. This means that it will sometimes feed us half a line in one payload and then the other half of that line in a subsequent payload. If the timing worked out, the log processor would see a partial line and (due to incomplete error handling) simply discard it, breaking the structure of the logs.

First Part

The most critical part of the change is switching the loops from

for len(s.Stdout.String()) > 0 {
  line, err := s.Stdout.ReadString('\n')

to

for strings.Contains(stream.buf.String(), "\n") {
  line, _ := stream.buf.ReadString('\n')

Basically, instead of looping until all the bytes are consumed, we loop until there are no more newlines in the buffer, thus potentially leaving a partial line in the buffer to be completed later. Because we now know that there must be a newline by the time we call ReadString we can skip its error-handling (from the golang docs: ReadString returns err != nil if and only if the returned data does not end in delim.).

Second Part

While working on this Claude pointed out that we were not handling the final line properly in Flush if it didn't itself end in a newline. Previously we would have just dropped it in Run, but since we were no longer dropping partial lines, Flush would time out waiting for the buffers to empty.

The fix is similar: instead of polling until the buffer is empty, poll until it has no more newlines. Then Flush itself processes any remaining partial lines as if they were a complete line.

Third Part

We ended up with four almost-identical blocks of code to process a log line (for Stdout-vs-Stderr and Flush-vs-Run). Refactored those into a helper method and logStream struct.

Changelog

  • List your changes here
  • Make a changie entry

Tophatting

Copy link
Copy Markdown
Contributor

@jasonopslevel jasonopslevel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested locally, lgtm!

@jasonopslevel jasonopslevel merged commit 5b63367 into main Apr 22, 2026
4 checks passed
@jasonopslevel jasonopslevel deleted the ehuus/fix-partial-log-lines branch April 22, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants