saluki_env/features/
detector.rs

1use saluki_config::GenericConfiguration;
2use tracing::info;
3
4use super::{has_host_mapped_cgroupfs, has_host_mapped_procfs, ContainerdDetector, Feature};
5
6/// Detects workload features.
7///
8/// The feature detector is used to determine which features are present in the workload, such as if the application is
9/// running in a Kubernetes environment or directly on Docker. This information is used to drive the collection of
10/// workload metadata that powers entity tagging.
11///
12/// `FeatureDetector` can be used in an automatic detection mode, where it will attempt to detect all features that are
13/// present, or it can be used to assert that a specific feature is present for scenarios where the feature is required,
14/// and the workload is already known upfront.
15#[derive(Clone)]
16pub struct FeatureDetector {
17    detected_features: Feature,
18}
19
20impl FeatureDetector {
21    /// Creates a new `FeatureDetector` that checks for all possible features.
22    pub fn automatic(config: &GenericConfiguration) -> Self {
23        Self::for_feature(config, Feature::all_bits())
24    }
25
26    /// Creates a new `FeatureDetector` that checks for the given feature(s).
27    ///
28    /// Multiple features can be checked for by combining the feature variants in a bitwise OR fashion.
29    pub fn for_feature(config: &GenericConfiguration, feature_mask: Feature) -> Self {
30        let detected_features = Self::detect_features(config, feature_mask);
31
32        Self { detected_features }
33    }
34
35    /// Checks if the given feature was detected and is available.
36    pub fn is_feature_available(&self, feature: Feature) -> bool {
37        self.detected_features.contains(feature)
38    }
39
40    fn detect_features(config: &GenericConfiguration, feature_mask: Feature) -> Feature {
41        let mut detected_features = Feature::none();
42
43        if feature_mask.contains(Feature::HostMappedProcfs) && has_host_mapped_procfs() {
44            info!("Detected presence of host-mapped procfs.");
45            detected_features |= Feature::HostMappedProcfs;
46        }
47
48        if feature_mask.contains(Feature::HostMappedCgroupfs) && has_host_mapped_cgroupfs() {
49            info!("Detected presence of host-mapped cgroupfs.");
50            detected_features |= Feature::HostMappedCgroupfs;
51        }
52
53        if feature_mask.contains(Feature::Containerd) && ContainerdDetector::detect_grpc_socket_path(config).is_some() {
54            info!("Detected presence of containerd.");
55            detected_features |= Feature::Containerd;
56        }
57
58        detected_features
59    }
60}