lablink_client_service.ship_logs¶
lablink_client_service.ship_logs
¶
Ships this container's own log stream to the allocator.
Log shipping is host-side in the AWS topology (user_data's
log_shipper.sh tails docker logs), but BYO clients have no
LabLink-controlled host process to rely on: run-locally boxes used a
detached CLI shipper that could die silently on operator laptops, and
hand-off clients (register --no-run-locally, e.g. a Run:AI
workload) never had any shipper at all — the container is its own
PID 1 with no docker daemon in sight. So BYO containers ship their own
stream: start.sh points fd 5 — the [tag]-prefixed output of every
service — at this worker's stdin when SHIP_LOGS=1.
That puts this worker IN the logging path, which imposes two hard rules (lablink#304's silent tail stall is the cautionary tale):
- Passthrough first. Every stdin line is written to stdout (container
PID-1 stdout, i.e.
docker logs) before anything else touches it, and the read loop never blocks on the network — shipping happens on a separate thread fed by a bounded drop-oldest queue. - Fail open. Missing env degrades to pure passthrough, and start.sh's
supervisor
exec cats after repeated crashes — the worst case is logs visible indocker logsbut absent from the allocator, never a frozen container.
Attributes¶
BATCH_SIZE = 50
module-attribute
¶
FLUSH_INTERVAL_S = 15
module-attribute
¶
LOG_GROUP = 'container-docker'
module-attribute
¶
MAX_RETRIES = 3
module-attribute
¶
POLL_INTERVAL_S = 1.0
module-attribute
¶
POST_TIMEOUT_S = 10
module-attribute
¶
QUEUE_MAX_LINES = 2000
module-attribute
¶
RETRY_BACKOFF_S = (1, 2, 4)
module-attribute
¶
Functions:¶
drain(queue, max_items=BATCH_SIZE)
¶
Pop up to max_items lines from the left of queue.
Source code in packages/client/src/lablink_client_service/ship_logs.py
main()
¶
Entry point for the ship_logs console script.
Source code in packages/client/src/lablink_client_service/ship_logs.py
post_batch(*, base_url, vm_name, headers, messages, retries=MAX_RETRIES, _sleep=time.sleep)
¶
POST one batch to /api/vm-logs/
Retries with backoff, then reports failure so the caller drops the batch. Unlike the deleted CLI shipper it never treats a 4xx as fatal: this worker is the only log channel BYO clients have and nothing respawns it for shipping-only failures, so a transient 401 while the allocator's DB warms up must degrade to a dropped batch, not a permanently dead shipper.
Source code in packages/client/src/lablink_client_service/ship_logs.py
read_loop(queue, stdin=None, stdout=None)
¶
Forward stdin to stdout line by line, queueing stamped copies.
The passthrough write happens FIRST and the loop touches nothing
that can block indefinitely besides stdin itself, so docker
logs output is byte-identical to running without this worker.
Returns on EOF (container shutdown).
Source code in packages/client/src/lablink_client_service/ship_logs.py
shipper_loop(queue, stop_event, post_fn, *, _monotonic=time.monotonic, poll_s=POLL_INTERVAL_S)
¶
Flush the queue on the 50-line / 15-second rule until stopped.
post_fn(messages, retries) does the actual POST. The stop path
performs a final single-attempt flush (no backoff) so a graceful
docker stop ships the tail inside docker's grace period.