Skip to content

Fix logs -n N truncating the oldest line at the read-chunk boundary#2000

Open
chengboonrong wants to merge 1 commit into
apple:mainfrom
chengboonrong:fix/logs-tail-partial-line
Open

Fix logs -n N truncating the oldest line at the read-chunk boundary#2000
chengboonrong wants to merge 1 commit into
apple:mainfrom
chengboonrong:fix/logs-tail-partial-line

Conversation

@chengboonrong

Copy link
Copy Markdown

Summary

container logs -n N truncated the oldest of the N returned lines whenever those
lines spanned more than one 1024-byte read chunk. For example, a single line
longer than 1024 bytes:

$ container logs -n 1 logbug | wc -c
1024        # expected ~3009; output also starts mid-line (leading "START" gone)

Root cause

Application.ContainerLogs.tail(fh:n:follow:) reads the file backward in
1024-byte chunks and stopped as soon as lines.count >= n. While offset > 0
the buffer starts in the middle of a line, so the first line in the buffer is a
fragment truncated at the chunk boundary — and Array(lines.suffix(n)) kept it.

Fix

Keep reading until there are more than n non-empty lines (so the first of
the n kept lines is guaranteed complete) or the start of the file is reached.
The backward read is extracted into a testable lastLines(fh:n:); the follow
and full-file paths are unchanged.

Tests

Adds ContainerLogsTests covering a single line longer than one chunk, N lines
spanning multiple chunks (the general case), the ordinary short-line case, and
N larger than the file. Verified locally: swift build,
swift format lint --strict, and the new tests all pass.

Fixes #1967

🤖 Generated with Claude Code

@chengboonrong
chengboonrong force-pushed the fix/logs-tail-partial-line branch from a6ca3d7 to ed87b89 Compare July 23, 2026 13:25
`tail` reads the log file backward in 1024-byte chunks and stopped as
soon as `lines.count >= n`. While `offset > 0` the buffer starts in the
middle of a line, so the first line in the buffer is a fragment
truncated at the chunk boundary. When the last N lines span more than
one chunk, `Array(lines.suffix(n))` kept that fragment, so the oldest
returned line was truncated -- e.g. `logs -n 1` on a single line longer
than 1024 bytes returned only its trailing 1024 bytes.

Keep reading until there are *more* than N non-empty lines (so the first
of the N kept lines is guaranteed complete) or the start of the file is
reached. Extracted the backward read into a testable `lastLines(fh:n:)`.

Fixes apple#1967

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Chris Cheng <chengchris8715@gmail.com>
@chengboonrong
chengboonrong force-pushed the fix/logs-tail-partial-line branch from ed87b89 to 0a23438 Compare July 23, 2026 13:38
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.

[Bug]: container logs -n N truncates the oldest line when it exceeds the 1024-byte read chunk

1 participant