[Bug]: `container machine logs -f` exits immediately when the log is empty

Open Beginner friendly
#2,492 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
swift
Domain
cli, testing

Research direction

Start in Sources/ContainerCommands/Machine/MachineLogs.swift around tail() lines 101–119, then compare the empty file behavior with the container logs -f fix in #2377 and check the shared tailer work in #2023. Confirm that following starts when the log is empty while non-following behavior remains unchanged; the issue asks for guidance on whether to fix this file or the shared tailer, so check the maintainers’ preferred direction before editing.

Written by the indexing model from the issue text.

Description

I have done the following
  • I have searched the existing issues
  • If possible, I've reproduced the issue using the 'main' branch of this project
Steps to reproduce

Hey folks, hope you're doing well!

Quick summary: container machine logs -f (without -n) exits right away with no output when the log file is empty, instead of waiting for new lines.

For context, container machine logs shows a machine VM's stdio log, or its boot log with --boot, and -f is meant to keep following it as new lines arrive.

What happens today, traced on main (d5416e63):

  1. Run container machine logs -f <machine> (or container machine logs --boot -f <machine>) while that log file is still empty, for example right after the machine starts.
  2. Without -n, tail() in Sources/ContainerCommands/Machine/MachineLogs.swift (around lines 101 to 105) does guard let data = try fh.readToEnd() else { return }.
  3. FileHandle.readToEnd() returns nil for a zero byte file (I checked this with a tiny Swift snippet on macOS).
  4. So tail() returns before it reaches if follow { followFile(fh:) } (around lines 116 to 119).
  5. The command exits immediately with no output and never follows the log.

Minimal repro of the Foundation part:

import Foundation

let path = NSTemporaryDirectory() + "empty.log"
FileManager.default.createFile(atPath: path, contents: Data())
let fh = try FileHandle(forReadingFrom: URL(fileURLWithPath: path))
print(try fh.readToEnd() as Any) // prints nil

Honest note: I haven't run this on a machine VM yet, I traced it in the code and confirmed the readToEnd() behavior with the snippet above.

Problem description

Expected: with -f, an empty log should just start following and print lines as they show up, same as container logs -f does now. Without -f, returning early is totally fine. The -n path (around lines 75 to 98) looks fine too.

This is the sibling of #2374, which was fixed for container logs in #2377. Big thanks to @i098 for that fix! The PR description mentions it deliberately left machine logs alone since they have a separate implementation, so I figured it was worth a dedicated issue.

A small heads up, in case it's useful: #2023 by @gnavadev (nice work on the tailing fixes there) moves both commands into a shared LogTailer.swift. As far as I can tell the shared tailer still has the guard ... else { return } form, so as written it wouldn't cover machine logs and might bring the empty log case back for container logs after it lands. I may well be missing something there, so happy to be corrected.

Which direction would you prefer?

  1. Mirror #2377 in MachineLogs.swift with } else if let data = try fh.readToEnd() {, so following still starts on an empty file.
  2. Fold the fix into the shared tailer from #2023, so both commands get it in one place.

I'd be glad to send a small PR for whichever you like, and any feedback or tips on how you'd want it tested would be really appreciated. Others are very welcome to weigh in too!

Environment
- OS: macOS 26.6.2 (25G83)
- Xcode: n/a (traced in source, not built locally)
- Container: main at d5416e63
Code of Conduct
  • I agree to follow this project's Code of Conduct
Dominant language
Swift
Stars
51.1k
Forks
1.8k
Avg merge
2d 10h
Merged PRs (30d)
37

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apple/container

All issues in apple/container

Similar issues

More Swift issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.