From 9f649226dd409f951a0f985cf2717cbe489deba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Fri, 31 May 2024 16:36:21 +1200 Subject: [PATCH] deps: add tracing feature to remove tracing dep if wanted --- Cargo.toml | 7 +++++-- src/generic_wrap.rs | 3 +++ src/std/job_object.rs | 13 +++++++------ src/std/process_group.rs | 17 +++++++++-------- src/std/process_session.rs | 5 +++-- src/std/reset_sigmask.rs | 6 ++++++ src/tokio/job_object.rs | 14 ++++++++------ src/tokio/process_group.rs | 17 +++++++++-------- src/tokio/process_session.rs | 5 +++-- src/tokio/reset_sigmask.rs | 6 ++++++ src/windows.rs | 14 ++++++++++---- 11 files changed, 69 insertions(+), 38 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 85ac392..3615639 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ rust-version = "1.75.0" futures = { version = "0.3.30", optional = true } indexmap = "2.2.6" tokio = { version = "1.37.0", features = ["io-util", "macros", "process", "rt"], optional = true } -tracing = "0.1.40" +tracing = { version = "0.1.40", optional = true } [target.'cfg(unix)'.dependencies] nix = { version = "0.28.0", default-features = false, features = ["fs", "poll", "signal"], optional = true } @@ -33,7 +33,10 @@ remoteprocess = "0.4.13" tokio = { version = "1.37.0", features = ["io-util", "macros", "process", "rt", "rt-multi-thread", "time"] } [features] -default = ["creation-flags", "job-object", "kill-on-drop", "process-group", "process-session"] +default = ["creation-flags", "job-object", "kill-on-drop", "process-group", "process-session", "tracing"] + +## Enable internal tracing logs +tracing = ["dep:tracing"] ## Frontend: StdCommandWrap std = ["dep:nix"] diff --git a/src/generic_wrap.rs b/src/generic_wrap.rs index 547aaeb..ce9c393 100644 --- a/src/generic_wrap.rs +++ b/src/generic_wrap.rs @@ -82,12 +82,14 @@ macro_rules! Wrap { wrappers: &mut ::indexmap::IndexMap<::std::any::TypeId, Box>, ) -> ::std::io::Result> { for (id, wrapper) in wrappers.iter_mut() { + #[cfg(feature = "tracing")] ::tracing::debug!(?id, "pre_spawn"); wrapper.pre_spawn(command, self)?; } let mut child = command.spawn()?; for (id, wrapper) in wrappers.iter_mut() { + #[cfg(feature = "tracing")] ::tracing::debug!(?id, "post_spawn"); wrapper.post_spawn(&mut child, self)?; } @@ -98,6 +100,7 @@ macro_rules! Wrap { ) as Box; for (id, wrapper) in wrappers.iter_mut() { + #[cfg(feature = "tracing")] ::tracing::debug!(?id, "wrap_child"); child = wrapper.wrap_child(child, self)?; } diff --git a/src/std/job_object.rs b/src/std/job_object.rs index ad84754..233ca3c 100644 --- a/src/std/job_object.rs +++ b/src/std/job_object.rs @@ -5,6 +5,7 @@ use std::{ time::Duration, }; +#[cfg(feature = "tracing")] use tracing::{debug, instrument}; use windows::Win32::{ Foundation::{CloseHandle, HANDLE}, @@ -33,7 +34,7 @@ use super::{StdChildWrapper, StdCommandWrap, StdCommandWrapper}; pub struct JobObject; impl StdCommandWrapper for JobObject { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn pre_spawn(&mut self, command: &mut Command, core: &StdCommandWrap) -> Result<()> { let mut flags = CREATE_SUSPENDED; #[cfg(feature = "creation-flags")] @@ -45,7 +46,7 @@ impl StdCommandWrapper for JobObject { Ok(()) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wrap_child( &mut self, inner: Box, @@ -82,7 +83,7 @@ pub struct JobObjectChild { } impl JobObjectChild { - #[instrument(level = "debug", skip(job_port))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(job_port)))] pub(crate) fn new(inner: Box, job_port: JobPort) -> Self { Self { inner, @@ -109,12 +110,12 @@ impl StdChildWrapper for JobObjectChild { self.inner.into_inner() } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn start_kill(&mut self) -> Result<()> { terminate_job(self.job_port.job, 1) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wait(&mut self) -> Result { if let ChildExitStatus::Exited(status) = &self.exit_status { return Ok(*status); @@ -133,7 +134,7 @@ impl StdChildWrapper for JobObjectChild { Ok(status) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn try_wait(&mut self) -> Result> { wait_on_job(self.job_port.completion_port, Some(Duration::ZERO))?; self.inner.try_wait() diff --git a/src/std/process_group.rs b/src/std/process_group.rs index b055044..4d44f0e 100644 --- a/src/std/process_group.rs +++ b/src/std/process_group.rs @@ -14,6 +14,7 @@ use nix::{ }, unistd::{setpgid, Pid}, }; +#[cfg(feature = "tracing")] use tracing::instrument; use crate::ChildExitStatus; @@ -61,7 +62,7 @@ pub struct ProcessGroupChild { } impl ProcessGroupChild { - #[instrument(level = "debug")] + #[cfg_attr(feature = "tracing", instrument(level = "debug"))] pub(crate) fn new(inner: Box, pgid: Pid) -> Self { Self { inner, @@ -79,7 +80,7 @@ impl ProcessGroupChild { } impl StdCommandWrapper for ProcessGroup { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn pre_spawn(&mut self, command: &mut Command, _core: &StdCommandWrap) -> Result<()> { #[cfg(Std_unstable)] { @@ -99,7 +100,7 @@ impl StdCommandWrapper for ProcessGroup { Ok(()) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wrap_child( &mut self, inner: Box, @@ -112,12 +113,12 @@ impl StdCommandWrapper for ProcessGroup { } impl ProcessGroupChild { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn signal_imp(&self, sig: Signal) -> Result<()> { killpg(self.pgid, sig).map_err(Error::from) } - #[instrument(level = "debug")] + #[cfg_attr(feature = "tracing", instrument(level = "debug"))] fn wait_imp(pgid: Pid, flag: WaitPidFlag) -> Result>> { // wait for processes in a loop until every process in this group has // exited (this ensures that we reap any zombies that may have been @@ -173,12 +174,12 @@ impl StdChildWrapper for ProcessGroupChild { self.inner.into_inner() } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn start_kill(&mut self) -> Result<()> { self.signal_imp(Signal::SIGKILL) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wait(&mut self) -> Result { if let ChildExitStatus::Exited(status) = &self.exit_status { return Ok(*status); @@ -194,7 +195,7 @@ impl StdChildWrapper for ProcessGroupChild { Ok(status) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn try_wait(&mut self) -> Result> { if let ChildExitStatus::Exited(status) = &self.exit_status { return Ok(Some(*status)); diff --git a/src/std/process_session.rs b/src/std/process_session.rs index 8b48157..42c9a0b 100644 --- a/src/std/process_session.rs +++ b/src/std/process_session.rs @@ -5,6 +5,7 @@ use std::{ }; use nix::unistd::{setsid, Pid}; +#[cfg(feature = "tracing")] use tracing::instrument; use super::{StdCommandWrap, StdCommandWrapper}; @@ -25,7 +26,7 @@ use super::{StdCommandWrap, StdCommandWrapper}; pub struct ProcessSession; impl StdCommandWrapper for ProcessSession { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn pre_spawn(&mut self, command: &mut Command, _core: &StdCommandWrap) -> Result<()> { unsafe { command.pre_exec(move || setsid().map_err(Error::from).map(|_| ())); @@ -34,7 +35,7 @@ impl StdCommandWrapper for ProcessSession { Ok(()) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wrap_child( &mut self, inner: Box, diff --git a/src/std/reset_sigmask.rs b/src/std/reset_sigmask.rs index 8f6a07b..adbdbf6 100644 --- a/src/std/reset_sigmask.rs +++ b/src/std/reset_sigmask.rs @@ -1,6 +1,7 @@ use std::{io::Result, os::unix::process::CommandExt, process::Command}; use nix::sys::signal::{sigprocmask, SigSet, SigmaskHow}; +#[cfg(feature = "tracing")] use tracing::trace; use super::{StdCommandWrap, StdCommandWrapper}; @@ -18,8 +19,13 @@ impl StdCommandWrapper for ResetSigmask { command.pre_exec(|| { let mut oldset = SigSet::empty(); let newset = SigSet::all(); + + #[cfg(feature = "tracing")] trace!(unblocking=?newset, "resetting process sigmask"); + sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&newset), Some(&mut oldset))?; + + #[cfg(feature = "tracing")] trace!(?oldset, "sigmask reset"); Ok(()) }); diff --git a/src/tokio/job_object.rs b/src/tokio/job_object.rs index 183ce88..0321156 100644 --- a/src/tokio/job_object.rs +++ b/src/tokio/job_object.rs @@ -4,6 +4,7 @@ use tokio::{ process::{Child, Command}, task::spawn_blocking, }; +#[cfg(feature = "tracing")] use tracing::{debug, instrument}; use windows::Win32::{ Foundation::{CloseHandle, HANDLE}, @@ -34,7 +35,7 @@ use super::{TokioChildWrapper, TokioCommandWrap, TokioCommandWrapper}; pub struct JobObject; impl TokioCommandWrapper for JobObject { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn pre_spawn(&mut self, command: &mut Command, core: &TokioCommandWrap) -> Result<()> { let mut flags = CREATE_SUSPENDED; #[cfg(feature = "creation-flags")] @@ -46,7 +47,7 @@ impl TokioCommandWrapper for JobObject { Ok(()) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wrap_child( &mut self, inner: Box, @@ -64,6 +65,7 @@ impl TokioCommandWrapper for JobObject { #[cfg(not(feature = "creation-flags"))] let create_suspended = false; + #[cfg(feature = "tracing")] debug!( ?kill_on_drop, ?create_suspended, @@ -97,7 +99,7 @@ pub struct JobObjectChild { } impl JobObjectChild { - #[instrument(level = "debug", skip(job_port))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(job_port)))] pub(crate) fn new(inner: Box, job_port: JobPort) -> Self { Self { inner, @@ -124,12 +126,12 @@ impl TokioChildWrapper for JobObjectChild { self.inner.into_inner() } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn start_kill(&mut self) -> Result<()> { terminate_job(self.job_port.job, 1) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wait(&mut self) -> Box> + Send + '_> { Box::new(async { if let ChildExitStatus::Exited(status) = &self.exit_status { @@ -160,7 +162,7 @@ impl TokioChildWrapper for JobObjectChild { }) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn try_wait(&mut self) -> Result> { wait_on_job(self.job_port.completion_port, Some(Duration::ZERO))?; self.inner.try_wait() diff --git a/src/tokio/process_group.rs b/src/tokio/process_group.rs index de7bc04..114ff1a 100644 --- a/src/tokio/process_group.rs +++ b/src/tokio/process_group.rs @@ -19,6 +19,7 @@ use tokio::{ process::{Child, Command}, task::spawn_blocking, }; +#[cfg(feature = "tracing")] use tracing::instrument; use crate::ChildExitStatus; @@ -66,7 +67,7 @@ pub struct ProcessGroupChild { } impl ProcessGroupChild { - #[instrument(level = "debug")] + #[cfg_attr(feature = "tracing", instrument(level = "debug"))] pub(crate) fn new(inner: Box, pgid: Pid) -> Self { Self { inner, @@ -84,7 +85,7 @@ impl ProcessGroupChild { } impl TokioCommandWrapper for ProcessGroup { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn pre_spawn(&mut self, command: &mut Command, _core: &TokioCommandWrap) -> Result<()> { #[cfg(tokio_unstable)] { @@ -104,7 +105,7 @@ impl TokioCommandWrapper for ProcessGroup { Ok(()) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wrap_child( &mut self, inner: Box, @@ -124,12 +125,12 @@ impl TokioCommandWrapper for ProcessGroup { } impl ProcessGroupChild { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn signal_imp(&self, sig: Signal) -> Result<()> { killpg(self.pgid, sig).map_err(Error::from) } - #[instrument(level = "debug")] + #[cfg_attr(feature = "tracing", instrument(level = "debug"))] fn wait_imp(pgid: Pid, flag: WaitPidFlag) -> Result>> { // wait for processes in a loop until every process in this group has // exited (this ensures that we reap any zombies that may have been @@ -185,12 +186,12 @@ impl TokioChildWrapper for ProcessGroupChild { self.inner.into_inner() } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn start_kill(&mut self) -> Result<()> { self.signal_imp(Signal::SIGKILL) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wait(&mut self) -> Box> + Send + '_> { Box::new(async { if let ChildExitStatus::Exited(status) = &self.exit_status { @@ -219,7 +220,7 @@ impl TokioChildWrapper for ProcessGroupChild { }) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn try_wait(&mut self) -> Result> { if let ChildExitStatus::Exited(status) = &self.exit_status { return Ok(Some(*status)); diff --git a/src/tokio/process_session.rs b/src/tokio/process_session.rs index e0995a9..5f4dfac 100644 --- a/src/tokio/process_session.rs +++ b/src/tokio/process_session.rs @@ -2,6 +2,7 @@ use std::io::{Error, Result}; use nix::unistd::{setsid, Pid}; use tokio::process::Command; +#[cfg(feature = "tracing")] use tracing::instrument; use super::{TokioCommandWrap, TokioCommandWrapper}; @@ -22,7 +23,7 @@ use super::{TokioCommandWrap, TokioCommandWrapper}; pub struct ProcessSession; impl TokioCommandWrapper for ProcessSession { - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn pre_spawn(&mut self, command: &mut Command, _core: &TokioCommandWrap) -> Result<()> { unsafe { command.pre_exec(move || setsid().map_err(Error::from).map(|_| ())); @@ -31,7 +32,7 @@ impl TokioCommandWrapper for ProcessSession { Ok(()) } - #[instrument(level = "debug", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "debug", skip(self)))] fn wrap_child( &mut self, inner: Box, diff --git a/src/tokio/reset_sigmask.rs b/src/tokio/reset_sigmask.rs index 7b536cb..f9e25a2 100644 --- a/src/tokio/reset_sigmask.rs +++ b/src/tokio/reset_sigmask.rs @@ -2,6 +2,7 @@ use std::io::Result; use nix::sys::signal::{sigprocmask, SigSet, SigmaskHow}; use tokio::process::Command; +#[cfg(feature = "tracing")] use tracing::trace; use super::{TokioCommandWrap, TokioCommandWrapper}; @@ -19,8 +20,13 @@ impl TokioCommandWrapper for ResetSigmask { command.pre_exec(|| { let mut oldset = SigSet::empty(); let newset = SigSet::all(); + + #[cfg(feature = "tracing")] trace!(unblocking=?newset, "resetting process sigmask"); + sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&newset), Some(&mut oldset))?; + + #[cfg(feature = "tracing")] trace!(?oldset, "sigmask reset"); Ok(()) }); diff --git a/src/windows.rs b/src/windows.rs index 21f17fd..4ba13cf 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -6,6 +6,7 @@ use std::{ time::Duration, }; +#[cfg(feature = "tracing")] use tracing::{debug, instrument}; use windows::Win32::{ Foundation::{CloseHandle, HANDLE, INVALID_HANDLE_VALUE}, @@ -47,12 +48,14 @@ unsafe impl Sync for JobPort {} /// /// If `kill_on_drop` is true, we opt into the `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE` flag, which /// essentially implements the "reap children" feature of Unix systems directly in Win32. -#[instrument(level = "debug")] +#[cfg_attr(feature = "tracing", instrument(level = "debug"))] pub(crate) fn make_job_object(handle: HANDLE, kill_on_drop: bool) -> Result { let job = unsafe { CreateJobObjectW(None, None) }.map_err(Error::other)?; + #[cfg(feature = "tracing")] debug!(?job, "done CreateJobObjectW"); let completion_port = unsafe { CreateIoCompletionPort(INVALID_HANDLE_VALUE, None, 0, 1) }?; + #[cfg(feature = "tracing")] debug!(?completion_port, "done CreateIoCompletionPort"); let associate_completion = JOBOBJECT_ASSOCIATE_COMPLETION_PORT { @@ -70,6 +73,7 @@ pub(crate) fn make_job_object(handle: HANDLE, kill_on_drop: bool) -> Result Result Result Result<()> { #[inline] unsafe fn inner(pid: u32, tool_handle: HANDLE) -> Result<()> { @@ -146,13 +152,13 @@ pub(crate) fn resume_threads(child_process: HANDLE) -> Result<()> { } /// Terminate a job object without waiting for the processes to exit. -#[instrument(level = "debug")] +#[cfg_attr(feature = "tracing", instrument(level = "debug"))] pub(crate) fn terminate_job(job: HANDLE, exit_code: u32) -> Result<()> { unsafe { TerminateJobObject(job, exit_code) }.map_err(Error::other) } /// Wait for a job to complete. -#[instrument(level = "debug")] +#[cfg_attr(feature = "tracing", instrument(level = "debug"))] pub(crate) fn wait_on_job( completion_port: HANDLE, timeout: Option,