From 1b5323a258ae2babb4601a67765cc064e15985a9 Mon Sep 17 00:00:00 2001 From: Sascha Brawer Date: Mon, 24 Aug 2026 19:47:26 +0200 Subject: [PATCH] feat: log available_parallelism() and version, structured, at startup Every internal thread pool (prune.rs/assemble.rs's own num_workers, Rayon's default global pool for conflate.match) sizes itself from std::thread::available_parallelism() -- which historically ignored Docker/podman's --cpus (a CFS bandwidth quota, not a cpuset) and just reported the host's full core count. Rust's std did fix this for cgroup v2 (rust-lang/rust#89310), and this toolchain (1.98) is well past that fix, but it's exactly the kind of library behavior worth confirming empirically rather than trusting -- this is that confirmation mechanism, for whenever a --cpus sweep (see docs/PRODUCTION.md) actually happens: log the value once, structured, and check it matches N under a real --cpus=N. While touching this call site: also moves the pipeline version out of the message text and into a structured field, matching this module's own documented convention (logging.rs's own doc comment: "Call sites that have actual structured data to log ... should attach it via the log crate's key-value API instead of interpolating it into the message text") -- the version was doing exactly that before. Keeps the "vX.Y.Z" form (concat!("v", env!("CARGO_PKG_VERSION")), a zero-cost compile-time concatenation of two string literals, not a runtime format!) to match both the previously-logged string and the release tag format (see RELEASING.md) -- not the bare semver pipeline::provenance's tool_component() uses, which is a different field for a different purpose. Extends logging::init()'s existing one-time startup log record rather than adding a second one -- already the natural, only-runs-once home for this kind of environment fact. Verified: cargo test (253 passed, extended the existing startup-record test to check both new structured fields instead of parsing the old message string)/clippy/fmt clean. Manually ran against the zugerland.osm.pbf fixture and confirmed the real JSON shape: {"fields":{"available_parallelism":10,"version":"v0.8.2"},..., "message":"pipeline starting up",...} Co-Authored-By: Claude Sonnet 5 --- src/pipeline/logging.rs | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/pipeline/logging.rs b/src/pipeline/logging.rs index 8351eacf..4996a19c 100644 --- a/src/pipeline/logging.rs +++ b/src/pipeline/logging.rs @@ -26,7 +26,7 @@ //! RUST_LOG still controls the level as usual, default `info`. use anyhow::{Context, Result}; -use std::{fs::OpenOptions, io::Write, path::Path}; +use std::{fs::OpenOptions, io::Write, path::Path, thread}; use time::{OffsetDateTime, format_description::well_known::Rfc3339}; const LOG_FILE_NAME: &str = "pipeline.log"; @@ -47,9 +47,20 @@ pub fn init(workdir: &Path) -> Result<()> { .target(env_logger::Target::Pipe(Box::new(file))) .init(); + // available_parallelism() is what every internal thread pool + // (prune.rs/assemble.rs's own worker counts, Rayon's default global + // pool for conflate.match) sizes itself from -- logged once here, + // structured, so a `--cpus=N` sweep (see docs/PRODUCTION.md) can + // actually confirm this returns N under a real cgroup CPU quota, + // rather than silently reporting the host's full core count. `Ok` + // wraps a `NonZero`; `.get()` down to a plain number for a + // cleaner logged field. `None` if the platform can't answer at + // all (see the stdlib's own docs on when this fails) -- worth + // recording as an absence, not worth failing pipeline startup over. log::info!( - "pipeline starting up, version=v{}", - env!("CARGO_PKG_VERSION") + version = concat!("v", env!("CARGO_PKG_VERSION")), + available_parallelism = thread::available_parallelism().map(|n| n.get()).ok(); + "pipeline starting up" ); Ok(()) } @@ -193,14 +204,17 @@ mod tests { .iter() .find(|r| r["target"] == init_module && r["level"] == "INFO") .with_context(|| format!("no startup record found among: {records:?}"))?; - assert!( - startup["message"] - .as_str() - .unwrap() - .contains(env!("CARGO_PKG_VERSION")), - "startup record should mention the binary's version: {startup}" + assert_eq!( + startup["fields"]["version"], + concat!("v", env!("CARGO_PKG_VERSION")) ); assert!(startup["timestamp"].as_str().is_some()); + assert!( + startup["fields"]["available_parallelism"] + .as_u64() + .is_some_and(|n| n >= 1), + "startup record should log a positive available_parallelism: {startup}" + ); let warn = records .iter()