saluki_env/workload/on_demand_pid/
mod.rs

1#[cfg(target_os = "linux")]
2use std::sync::Arc;
3
4use saluki_config::GenericConfiguration;
5use saluki_error::GenericError;
6use stringtheory::interning::GenericMapInterner;
7
8use crate::{features::FeatureDetector, workload::EntityId};
9
10#[cfg(target_os = "linux")]
11mod linux;
12
13/// A resolver for mapping process IDs to their container IDs based on querying the underlying host.
14///
15/// # Platform support
16///
17/// On Linux, PIDs are resolved by querying procfs to find the cgroup of the process, if one exists, the cgroup
18/// hierarchy is queried to discover the container ID that owns the process, if possible.
19///
20/// On all other platforms, resolving a PID is a no-op.
21#[derive(Clone)]
22pub struct OnDemandPIDResolver {
23    #[cfg(target_os = "linux")]
24    inner: Arc<linux::ResolverImpl>,
25    #[cfg(not(target_os = "linux"))]
26    _empty: (),
27}
28
29impl OnDemandPIDResolver {
30    /// Creates a new `OnDemandPIDResolver` from the given configuration.
31    ///
32    /// # Errors
33    ///
34    /// If a cgroups hierarchy can't be found, or the internal cache can't be created, an error is returned.
35    pub fn from_configuration(
36        config: &GenericConfiguration, feature_detector: FeatureDetector, interner: GenericMapInterner,
37    ) -> Result<Self, GenericError> {
38        #[cfg(target_os = "linux")]
39        {
40            let resolver_inner = linux::ResolverImpl::from_configuration(config, feature_detector, interner)?;
41            Ok(Self {
42                inner: Arc::new(resolver_inner),
43            })
44        }
45
46        #[cfg(not(target_os = "linux"))]
47        {
48            // Rebind to make compiler happy.
49            let _config = config;
50            let _feature_detector = feature_detector;
51            let _interner = interner;
52
53            Ok(Self { _empty: () })
54        }
55    }
56
57    /// Resolves a process ID to the container ID of the container is part of.
58    ///
59    /// If the process ID isn't part of a container, or can't be found, `None` is returned.
60    pub fn resolve(&self, process_id: u32) -> Option<EntityId> {
61        #[cfg(target_os = "linux")]
62        let resolved = self.inner.resolve(process_id);
63
64        #[cfg(not(target_os = "linux"))]
65        let resolved = {
66            // Rebind to make compiler happy.
67            let _process_id = process_id;
68            None
69        };
70
71        resolved
72    }
73
74    /// Resolves the current process's container entity from local cgroup membership.
75    ///
76    /// On non-Linux platforms, or when the process is not in a recognizable container cgroup, this returns `None`.
77    pub fn resolve_self_container(&self) -> Option<EntityId> {
78        #[cfg(target_os = "linux")]
79        let resolved = self.inner.resolve_self_container();
80
81        #[cfg(not(target_os = "linux"))]
82        let resolved = None;
83
84        resolved
85    }
86}