// Reuse sysinfo's native OS APIs on Linux, BSD, macOS and Windows. The // diagnostics endpoint must never spawn system commands or parse platform files. // Host identification is cached because it changes only after a reboot. fn valid_host_text(value: String) -> Option { let value = value.trim(); (!value.is_empty() && value.len() <= 128 && !value.chars().any(char::is_control)) .then(|| value.to_owned()) } fn os_release() -> Option<&'static str> { static VALUE: std::sync::OnceLock> = std::sync::OnceLock::new(); VALUE.get_or_init(|| { sysinfo::System::long_os_version() .or_else(|| { let name = sysinfo::System::name()?; Some(match sysinfo::System::os_version() { Some(version) if !version.is_empty() => format!("{name} {version}"), _ => name, }) }) .and_then(valid_host_text) }).as_deref() } fn kernel_release() -> Option<&'static str> { static VALUE: std::sync::OnceLock> = std::sync::OnceLock::new(); VALUE.get_or_init(|| sysinfo::System::kernel_version().and_then(valid_host_text)) .as_deref() } // Cached diagnostics and ACME metadata are requested separately from high-rate SSE. // Preserve the legacy full /api/status shape for existing API clients. fn system_info_payload(state: &App) -> Value { let cache_view = state.cache.view(); let transform_resources = crate::transform::resource_usage(&state.config.load().envelope.config.transform); let mut payload = json!({}); let system = state.diagnostics.view(); let cache_ram_bytes = (cache_view.hot_allocated_bytes as u64).saturating_add(cache_view.transient_bytes); let non_cache_rss_bytes = system .process_rss_bytes .map(|rss| rss.saturating_sub(cache_ram_bytes)); payload["memory_accounting"] = json!({ "process_rss_bytes": system.process_rss_bytes, "cache_hot_bytes": cache_view.hot_allocated_bytes, "cache_hot_limit_bytes": cache_view.hot_limit_bytes, "cache_transient_bytes": cache_view.transient_bytes, "cache_transient_limit_bytes": cache_view.transient_limit_bytes, "cache_total_bytes": cache_ram_bytes, "transform_reserved_bytes": transform_resources.memory_reserved_bytes, "transform_budget_bytes": transform_resources.memory_budget_bytes, "transform_inflight": transform_resources.inflight, "transform_max_inflight": transform_resources.max_inflight, "non_cache_rss_bytes": non_cache_rss_bytes, "non_cache_rss_includes_transform": true, "method": "rss_minus_accounted_cache; transform reservation is an overlapping estimate" }); payload["runtime"] = json!({ "platform": system.platform, "operating_system": os_release(), "kernel_version": kernel_release(), "architecture": std::env::consts::ARCH, "statistics_source": system.source, "data_directory": state.policy.data_dir.as_ref().map(|path| path.display().to_string()), "database_path": state.policy.data_dir.as_ref().map(|path| path.join("config.sqlite3").display().to_string()), "certificate_runtime": state.acme.runtime_view() }); payload["system"] = json!(system); payload }