Skip to main content

sc_observability_types/
process.rs

1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4
5use crate::IdentityError;
6
7/// Caller-resolved process identity attached to observations and log events.
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
9pub struct ProcessIdentity {
10    /// Optional hostname attached to the event or observation.
11    pub hostname: Option<String>,
12    /// Optional process identifier attached to the event or observation.
13    pub pid: Option<u32>,
14}
15
16/// Policy describing how process identity is populated at runtime.
17pub enum ProcessIdentityPolicy {
18    /// Resolve process identity automatically using the default runtime behavior.
19    Auto,
20    /// Use a fixed caller-supplied identity.
21    Fixed {
22        /// Fixed hostname value.
23        hostname: Option<String>,
24        /// Fixed process identifier value.
25        pid: Option<u32>,
26    },
27    /// Delegate identity resolution to a caller-supplied resolver.
28    Resolver(Arc<dyn ProcessIdentityResolver>),
29}
30
31impl std::fmt::Debug for ProcessIdentityPolicy {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        match self {
34            Self::Auto => f.write_str("ProcessIdentityPolicy::Auto"),
35            Self::Fixed { hostname, pid } => f
36                .debug_struct("ProcessIdentityPolicy::Fixed")
37                .field("hostname", hostname)
38                .field("pid", pid)
39                .finish(),
40            Self::Resolver(_) => {
41                f.write_str("ProcessIdentityPolicy::Resolver(<dyn ProcessIdentityResolver>)")
42            }
43        }
44    }
45}
46
47/// Open resolver contract for caller-defined process identity lookup.
48pub trait ProcessIdentityResolver: Send + Sync {
49    /// Resolves the process identity to attach to emitted records.
50    ///
51    /// # Errors
52    ///
53    /// Returns [`IdentityError`] when the resolver cannot produce a valid
54    /// process identity.
55    fn resolve(&self) -> Result<ProcessIdentity, IdentityError>;
56}
57
58#[cfg(test)]
59mod tests {
60    use std::sync::Arc;
61
62    use super::*;
63
64    struct FixtureResolver;
65
66    impl ProcessIdentityResolver for FixtureResolver {
67        fn resolve(&self) -> Result<ProcessIdentity, IdentityError> {
68            Ok(ProcessIdentity::default())
69        }
70    }
71
72    #[test]
73    fn process_identity_policy_fixed_debug_is_descriptive() {
74        let policy = ProcessIdentityPolicy::Fixed {
75            hostname: Some("host-1".to_string()),
76            pid: Some(42),
77        };
78
79        assert_eq!(
80            format!("{policy:?}"),
81            "ProcessIdentityPolicy::Fixed { hostname: Some(\"host-1\"), pid: Some(42) }"
82        );
83    }
84
85    #[test]
86    fn process_identity_policy_resolver_debug_is_descriptive() {
87        let policy = ProcessIdentityPolicy::Resolver(Arc::new(FixtureResolver));
88
89        assert_eq!(
90            format!("{policy:?}"),
91            "ProcessIdentityPolicy::Resolver(<dyn ProcessIdentityResolver>)"
92        );
93    }
94
95    #[test]
96    fn process_identity_policy_auto_debug_is_descriptive() {
97        assert_eq!(
98            format!("{:?}", ProcessIdentityPolicy::Auto),
99            "ProcessIdentityPolicy::Auto"
100        );
101    }
102}