Skip to content

Add a --server-log-mode option to qlever start - #336

Merged
hannahbast merged 3 commits into
mainfrom
server-log-mode
Sep 4, 2026
Merged

Add a --server-log-mode option to qlever start#336
hannahbast merged 3 commits into
mainfrom
server-log-mode

Conversation

@hannahbast

@hannahbast hannahbast commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Until now, qlever start removed the server log of the previous run before starting the server. This has repeatedly destroyed the evidence needed to diagnose a server crash. The new option --server-log-mode (also settable via SERVER_LOG_MODE in the [server] section of the Qleverfile) controls what happens to an existing <name>.server-log.txt:

  • rotate (the new default): move it to <log>.1, shifting older generations up; all generations are kept.
  • overwrite: remove it (the behavior so far).
  • append: keep it and append; only the output of the new run is followed on the console.
  • no-log: write no server log at all; when the server runs in the foreground, its output goes to the terminal.

Until now, `qlever start` removed the server log of the previous run
before starting the server. This has repeatedly destroyed the evidence
needed to diagnose a server crash. The new option controls what happens
to an existing `<name>.server-log.txt`: `rotate` (the new default) moves
it to `<log>.1`, shifting older generations up (all are kept);
`overwrite` removes it as before; `append` keeps it and appends (only
the new run is followed on the console); `no-log` writes no server log
at all. Can also be set via `SERVER_LOG_MODE` in the `[server]` section
of the Qleverfile.
Copilot AI lite review requested due to automatic review settings September 4, 2026 11:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

--server-log-mode no-log in foreground currently won’t actually stream output to the terminal (and may block on piped output), and there are shell-quoting/shell=True issues around log handling that should be fixed.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds a new --server-log-mode option to qlever start (also configurable via the Qleverfile) to control how an existing <name>.server-log.txt is handled, preventing loss of crash evidence from previous runs.

Changes:

  • Added --server-log-mode (rotate default; append, overwrite, no-log) and wired it into qlever start.
  • Implemented server-log rotation and adjusted log tailing behavior to optionally follow only newly appended output.
  • Added tests covering append/no-log command construction and log rotation behavior.
File summaries
File Description
test/qlever/commands/test_start_other_methods.py Adds server_log_mode to the list of Qleverfile-relevant arguments tested.
test/qlever/commands/test_start_execute.py Adds tests for append/no-log command construction and rotate_server_log.
src/qlever/util.py Extends tail_log_file with from_beginning control for append-follow semantics.
src/qlever/qleverfile.py Adds CLI parsing/help for --server-log-mode.
src/qlever/commands/start.py Implements the new log-mode behaviors in command construction and execution flow (rotation, append follow, no-log).
Review details

Suppressed comments (1)

src/qlever/util.py:764

  • The tail_log_file docstring still states it always tails “from the beginning” and that the old log file should be deleted first, but the new from_beginning parameter (and append mode) intentionally tails only new lines without deleting/rotating the existing file. Please update the docstring to reflect the new behavior.
    from_beginning: bool = True,
) -> subprocess.Popen | None:
    """
    Wait for the log file to appear and start tailing it from the
    beginning. The old log file should be deleted before calling this
  • Files reviewed: 5/5 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +102 to 105
else:
redirect = ">>" if args.server_log_mode == "append" else ">"
start_cmd += f" {redirect} {args.name}.server-log.txt 2>&1"
return start_cmd
Comment on lines +513 to +517
if args.run_in_foreground:
log.info(
"No server log is written, the server output goes to "
"this terminal (Ctrl-C stops the server)"
)
Comment thread src/qlever/util.py
Comment on lines +780 to 782
tail_from = "+1" if from_beginning else "0"
tail_cmd = f"exec tail -n {tail_from} -f {log_file}"
return subprocess.Popen(tail_cmd, shell=True)
Comment on lines 301 to +303
on_interrupt()
log_proc.terminate()
if log_proc is not None:
log_proc.terminate()
With `--server-log-mode no-log` and `--run-in-foreground`, the server
output now really goes to the terminal (without a redirection in the
command, it went to a pipe that nobody reads, which would eventually
block the server). Also fix the type annotation of `log_proc`, which
can be `None` now.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Foreground no-log output is captured instead of displayed, while append mode can miss startup output.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (3)

src/qlever/commands/start.py:101

  • In foreground no-log mode this does not actually send output to the terminal. execute launches the command with run_command(..., use_popen=True), whose defaults capture both streams in subprocess.PIPE (src/qlever/util.py:82-95), and nothing drains those pipes. The output is therefore hidden and a verbose server can block once the pipe buffers fill. Launch this mode with show_output=True and show_stderr=True.
    if args.server_log_mode == "no-log":
        # No log file is written. In the foreground, the server output
        # goes to the terminal; in the background, it is discarded.
        if not args.run_in_foreground:
            start_cmd += " > /dev/null 2>&1"

src/qlever/commands/start.py:528

  • The follower is started only after the server command has returned/launched, so tail -n 0 seeks to EOF after some startup output may already have been appended. Those lines are from the new run but will never be shown, contrary to append mode's contract. Record the pre-launch byte offset and tail from it, or start the follower before launching the server.
            tail_proc = tail_log_file(
                log_file, from_beginning=args.server_log_mode != "append"
            )

src/qlever/commands/start.py:303

  • This guard makes None a supported value, and execute now passes None in no-log mode, but the parameter remains annotated as subprocess.Popen. Update the type contract to include None.
    if log_proc is not None:
        log_proc.terminate()
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread src/qlever/commands/start.py
Comment thread src/qlever/util.py
def tail_log_file(
log_file: Path,
max_wait_seconds: int = 30,
from_beginning: bool = True,
@hannahbast
hannahbast merged commit ff50123 into main Sep 4, 2026
10 checks passed
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