diff --git a/opentelemetry-resource-detectors/CHANGELOG.md b/opentelemetry-resource-detectors/CHANGELOG.md index 1296b675..e4a3fed7 100644 --- a/opentelemetry-resource-detectors/CHANGELOG.md +++ b/opentelemetry-resource-detectors/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## vNext + +### Added + +- Added `HostResourceDetector` which populates "host.id" attribute. Currently only Linux is supported. + ## v0.1.0 ### Added diff --git a/opentelemetry-resource-detectors/README.md b/opentelemetry-resource-detectors/README.md index 54497858..50fdc33a 100644 --- a/opentelemetry-resource-detectors/README.md +++ b/opentelemetry-resource-detectors/README.md @@ -12,7 +12,8 @@ Community supported Resource detectors implementations for applications instrume ## Features -| Detector | Implemented Resources | Semantic Conventions | -| -------------- | --------------------------------------------------- | -------------------------- | -| ProcessResourceDetector | PROCESS_COMMAND_ARGS, PROCESS_PID | https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.x/specification/resource/semantic_conventions/process.md | -| OsResourceDetector | OS_TYPE | https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.x/specification/resource/semantic_conventions/os.md | +| Detector | Implemented Resources | OS Supported | Semantic Conventions | +|-------------------------| --------------------------------------------------- |--------------|-------------------------------------------------------------------------------------------| +| ProcessResourceDetector | PROCESS_COMMAND_ARGS, PROCESS_PID | all | https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/process.md | +| OsResourceDetector | OS_TYPE | all | https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/os.md | +| HostResourceDetector | HOST_ID | linux | https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/host.md | \ No newline at end of file diff --git a/opentelemetry-resource-detectors/src/host.rs b/opentelemetry-resource-detectors/src/host.rs new file mode 100644 index 00000000..6a775092 --- /dev/null +++ b/opentelemetry-resource-detectors/src/host.rs @@ -0,0 +1,73 @@ +//! HOST resource detector +//! +//! Detect the unique host ID. +use opentelemetry::KeyValue; +use opentelemetry_sdk::resource::ResourceDetector; +use opentelemetry_sdk::Resource; +use std::fs::read_to_string; +use std::path::Path; +use std::time::Duration; + +/// Detect the unique host ID. +/// +/// This detector looks up the host id using the sources defined +/// in the OpenTelemetry semantic conventions [`host.id from non-containerized systems`]. +/// +/// [`host.id from non-containerized systems`]: https://opentelemetry.io/docs/specs/semconv/resource/host/#collecting-hostid-from-non-containerized-systems +pub struct HostResourceDetector { + host_id_detect: fn() -> Option, +} + +impl ResourceDetector for HostResourceDetector { + fn detect(&self, _timeout: Duration) -> Resource { + (self.host_id_detect)() + .map(|host_id| { + Resource::new(vec![KeyValue::new( + opentelemetry_semantic_conventions::resource::HOST_ID, + host_id, + )]) + }) + .unwrap_or(Resource::new(vec![])) + } +} + +#[cfg(target_os = "linux")] +fn host_id_detect() -> Option { + let machine_id_path = Path::new("/etc/machine-id"); + let dbus_machine_id_path = Path::new("/var/lib/dbus/machine-id"); + read_to_string(machine_id_path) + .or_else(|_| read_to_string(dbus_machine_id_path)) + .ok() +} + +// TODO: Implement non-linux platforms +#[cfg(not(target_os = "linux"))] +fn host_id_detect() -> Option { + None +} + +impl Default for HostResourceDetector { + fn default() -> Self { + Self { host_id_detect } + } +} + +#[cfg(target_os = "linux")] +#[cfg(test)] +mod tests { + use super::HostResourceDetector; + use opentelemetry::Key; + use opentelemetry_sdk::resource::ResourceDetector; + use std::time::Duration; + + #[test] + fn test_host_resource_detector() { + let resource = HostResourceDetector::default().detect(Duration::from_secs(0)); + assert_eq!(resource.len(), 1); + assert!(resource + .get(Key::from_static_str( + opentelemetry_semantic_conventions::resource::HOST_ID + )) + .is_some()) + } +} diff --git a/opentelemetry-resource-detectors/src/lib.rs b/opentelemetry-resource-detectors/src/lib.rs index 76ed4b4e..61837690 100644 --- a/opentelemetry-resource-detectors/src/lib.rs +++ b/opentelemetry-resource-detectors/src/lib.rs @@ -5,8 +5,11 @@ //! //! - [`OsResourceDetector`] - detect OS from runtime. //! - [`ProcessResourceDetector`] - detect process information. +//! - [`HostResourceDetector`] - detect unique host ID. +mod host; mod os; mod process; +pub use host::HostResourceDetector; pub use os::OsResourceDetector; pub use process::ProcessResourceDetector;