[Bug]: `container logs -n N` truncates the oldest line when it exceeds the 1024-byte read chunk
- Dominant language
- Swift
- Stars
- 49.9k
- Forks
- 1.8k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 22
Description
### Steps to reproduce
1. Start a container that logs a single line longer than 1024 bytes:
```
container run -d --name logbug alpine \
sh -c 'printf "START"; i=0; while [ $i -lt 3000 ]; do printf "X"; i=$((i+1)); done; printf "END\n"; sleep 120'
```
2. `container logs -n 1 logbug | wc -c`
### Current behavior
Returns **1024 bytes**, and the output starts in the middle of the line — the leading `START` is gone. The oldest (here, only) returned line is truncated.
### Expected behavior
Returns the full line (~3009 bytes), matching `container logs logbug` (without `-n`), which returns the complete line.
More generally, `container logs -n N` truncates the oldest of the N returned lines whenever the last N lines span more than one 1024-byte read chunk (e.g. three ~800-byte lines with `-n 2`).
### Root cause
`Application.ContainerLogs.tail(fh:n:follow:)` reads the file backwards in 1024-byte chunks and stops as soon as `lines.count >= n`. When the last N lines span more than one chunk, the first line in the buffer is a fragment truncated at the chunk boundary (the buffer starts mid-line while `offset > 0`), and `Array(lines.suffix(n))` keeps it. It should keep reading until it has *more* than N non-empty lines (so the partial leading line is dropped) or reaches the start of the file.
### Environment
- container 1.1.0
- macOS 26.5 (Tahoe), Apple Silicon (M-series)
Contributor guide
Research direction
Start at Application.ContainerLogs.tail(fh:n:follow:) and reproduce the issue with the supplied `container logs -n 1 logbug | wc -c` command. Trace the backwards 1024-byte reads and verify that `container logs -n N` preserves the complete oldest returned line, including when it crosses a chunk boundary.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100