From c3f0a306b465f43bc4b9ad4a9b7a16de0728e34c Mon Sep 17 00:00:00 2001 From: archipelago Date: Thu, 9 Jul 2026 03:09:08 -0400 Subject: [PATCH] =?UTF-8?q?fix(observability):=20mirror=20install=5Flog()?= =?UTF-8?q?=20to=20tracing=20=E2=80=94=20file=20append=20is=20sandbox-dead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /var/log/archipelago/container-installs.log has been 0 bytes since April: the service sandbox (ProtectSystem=strict class) leaves /var/log read-only for the unit, the open() fails, and install_log() drops every line by design (fire-and-forget). These START/STOP/RESTART/FAIL breadcrumbs are the primary forensic trail for gate failures, so mirror every line to tracing (journald) unconditionally and keep the file append as best-effort for hosts where the path is writable. Co-Authored-By: Claude Fable 5 --- core/archipelago/src/api/rpc/package/install.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/archipelago/src/api/rpc/package/install.rs b/core/archipelago/src/api/rpc/package/install.rs index 70570b0a..90c21901 100644 --- a/core/archipelago/src/api/rpc/package/install.rs +++ b/core/archipelago/src/api/rpc/package/install.rs @@ -24,6 +24,12 @@ const IMAGE_INSPECT_TIMEOUT: Duration = Duration::from_secs(10); /// Append a timestamped line to the persistent install log. pub(in crate::api::rpc) async fn install_log(msg: &str) { use tokio::io::AsyncWriteExt; + // Always mirror to tracing/journald: the file append below has been + // silently failing under the service sandbox (ProtectSystem=strict + // leaves /var/log/archipelago read-only — container-installs.log has + // been 0 bytes since April 2026), and these lifecycle breadcrumbs are + // the primary forensic trail for gate failures. + info!(target: "install_log", "{msg}"); let ts = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC"); let line = format!("[{}] {}\n", ts, msg); if let Ok(mut f) = tokio::fs::OpenOptions::new()