Skip to content

lablink_allocator_service.utils.log_tail

Bounded reads of the allocator's own log file.

start.sh tees this container's entire stdout/stderr through rotatelogs into LOG_DIR, and this module is the only way the allocator can show that output: nothing mounts docker.sock, so it cannot run docker logs on itself.

Flask-free on purpose -- the tailing and redaction logic is the part worth testing, and keeping it out of the route module lets it test against tmp_path with no app fixture.

Last max_lines lines across the rotation set, cleaned and redacted.

Returns None when there is no log file to read at all -- the caller turns that into a user-facing explanation rather than an error.

Source code in packages/allocator/src/lablink_allocator_service/utils/log_tail.py
def read_allocator_log(
    log_dir: Path = LOG_DIR,
    max_lines: int = DEFAULT_MAX_LINES,
) -> str | None:
    """Last `max_lines` lines across the rotation set, cleaned and redacted.

    Returns None when there is no log file to read at all -- the caller
    turns that into a user-facing explanation rather than an error.
    """
    chunks = []
    for path in _rotation_files(log_dir):
        try:
            chunks.append(_tail_bytes(path, _TAIL_WINDOW_BYTES))
        except OSError:
            continue
    if not chunks:
        return None

    # The byte window can slice mid-line, leaving a fragmentary first
    # line. Harmless: _TAIL_WINDOW_BYTES holds far more than max_lines of
    # ordinary output, so the slice below almost always discards it.
    lines = "".join(chunks).splitlines()[-max_lines:]
    # Werkzeug colorizes non-2xx request lines, so this stream carries ANSI
    # escapes that the log box would render as literal junk. Client VM logs
    # reach the same template already clean -- vm_telemetry strips them at
    # ingestion -- so strip here to match.
    return redact_secrets(strip_ansi("\n".join(lines))) or None

Mask the values of secret-looking assignments, keeping the keys.

Source code in packages/allocator/src/lablink_allocator_service/utils/log_tail.py
def redact_secrets(text: str) -> str:
    """Mask the values of secret-looking assignments, keeping the keys."""
    return _SECRET_RE.sub(rf"\1{_REDACTED}", text)