From 6834b6419250fa77a36c2430d171f4362473c5ec Mon Sep 17 00:00:00 2001 From: Zhongyang Wu Date: Wed, 16 Jun 2021 00:38:48 -0400 Subject: [PATCH] feat: add more resource detectors (#573) --- opentelemetry-otlp/src/proto/grpcio/common.rs | 4 +- .../src/proto/grpcio/metrics.rs | 4 +- .../src/proto/grpcio/metrics_service.rs | 4 +- .../src/proto/grpcio/resource.rs | 4 +- opentelemetry-otlp/src/proto/grpcio/trace.rs | 4 +- .../src/proto/grpcio/trace_config.rs | 4 +- .../src/proto/grpcio/trace_service.rs | 4 +- opentelemetry/src/sdk/mod.rs | 2 - opentelemetry/src/sdk/{ => resource}/env.rs | 7 ++- .../src/sdk/{resource.rs => resource/mod.rs} | 20 +++++++- opentelemetry/src/sdk/resource/os.rs | 46 +++++++++++++++++ opentelemetry/src/sdk/resource/process.rs | 51 +++++++++++++++++++ 12 files changed, 132 insertions(+), 22 deletions(-) rename opentelemetry/src/sdk/{ => resource}/env.rs (93%) rename opentelemetry/src/sdk/{resource.rs => resource/mod.rs} (93%) create mode 100644 opentelemetry/src/sdk/resource/os.rs create mode 100644 opentelemetry/src/sdk/resource/process.rs diff --git a/opentelemetry-otlp/src/proto/grpcio/common.rs b/opentelemetry-otlp/src/proto/grpcio/common.rs index 0dde05ad18..575fef76ea 100644 --- a/opentelemetry-otlp/src/proto/grpcio/common.rs +++ b/opentelemetry-otlp/src/proto/grpcio/common.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.23.0. Do not edit +// This file is generated by rust-protobuf 2.24.1. Do not edit // @generated // https://github.com/rust-lang/rust-clippy/issues/702 @@ -21,7 +21,7 @@ /// Generated files are compatible only with the same version /// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_24_1; #[derive(PartialEq,Clone,Default)] #[cfg_attr(feature = "with-serde", derive(::serde::Serialize, ::serde::Deserialize))] diff --git a/opentelemetry-otlp/src/proto/grpcio/metrics.rs b/opentelemetry-otlp/src/proto/grpcio/metrics.rs index 1e93bd17fd..202b34b7b9 100644 --- a/opentelemetry-otlp/src/proto/grpcio/metrics.rs +++ b/opentelemetry-otlp/src/proto/grpcio/metrics.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.23.0. Do not edit +// This file is generated by rust-protobuf 2.24.1. Do not edit // @generated // https://github.com/rust-lang/rust-clippy/issues/702 @@ -21,7 +21,7 @@ /// Generated files are compatible only with the same version /// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_24_1; #[derive(PartialEq,Clone,Default)] #[cfg_attr(feature = "with-serde", derive(::serde::Serialize, ::serde::Deserialize))] diff --git a/opentelemetry-otlp/src/proto/grpcio/metrics_service.rs b/opentelemetry-otlp/src/proto/grpcio/metrics_service.rs index a188fdd508..811b7eece8 100644 --- a/opentelemetry-otlp/src/proto/grpcio/metrics_service.rs +++ b/opentelemetry-otlp/src/proto/grpcio/metrics_service.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.23.0. Do not edit +// This file is generated by rust-protobuf 2.24.1. Do not edit // @generated // https://github.com/rust-lang/rust-clippy/issues/702 @@ -21,7 +21,7 @@ /// Generated files are compatible only with the same version /// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_24_1; #[derive(PartialEq,Clone,Default)] #[cfg_attr(feature = "with-serde", derive(::serde::Serialize, ::serde::Deserialize))] diff --git a/opentelemetry-otlp/src/proto/grpcio/resource.rs b/opentelemetry-otlp/src/proto/grpcio/resource.rs index 4bf7b9f430..c1a1f265ad 100644 --- a/opentelemetry-otlp/src/proto/grpcio/resource.rs +++ b/opentelemetry-otlp/src/proto/grpcio/resource.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.23.0. Do not edit +// This file is generated by rust-protobuf 2.24.1. Do not edit // @generated // https://github.com/rust-lang/rust-clippy/issues/702 @@ -21,7 +21,7 @@ /// Generated files are compatible only with the same version /// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_24_1; #[derive(PartialEq,Clone,Default)] #[cfg_attr(feature = "with-serde", derive(::serde::Serialize, ::serde::Deserialize))] diff --git a/opentelemetry-otlp/src/proto/grpcio/trace.rs b/opentelemetry-otlp/src/proto/grpcio/trace.rs index f1f943266b..8bd5a12d5a 100644 --- a/opentelemetry-otlp/src/proto/grpcio/trace.rs +++ b/opentelemetry-otlp/src/proto/grpcio/trace.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.23.0. Do not edit +// This file is generated by rust-protobuf 2.24.1. Do not edit // @generated // https://github.com/rust-lang/rust-clippy/issues/702 @@ -21,7 +21,7 @@ /// Generated files are compatible only with the same version /// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_24_1; #[derive(PartialEq,Clone,Default)] #[cfg_attr(feature = "with-serde", derive(::serde::Serialize, ::serde::Deserialize))] diff --git a/opentelemetry-otlp/src/proto/grpcio/trace_config.rs b/opentelemetry-otlp/src/proto/grpcio/trace_config.rs index 26f8c66ab4..9987eadada 100644 --- a/opentelemetry-otlp/src/proto/grpcio/trace_config.rs +++ b/opentelemetry-otlp/src/proto/grpcio/trace_config.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.23.0. Do not edit +// This file is generated by rust-protobuf 2.24.1. Do not edit // @generated // https://github.com/rust-lang/rust-clippy/issues/702 @@ -21,7 +21,7 @@ /// Generated files are compatible only with the same version /// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_24_1; #[derive(PartialEq,Clone,Default)] #[cfg_attr(feature = "with-serde", derive(::serde::Serialize, ::serde::Deserialize))] diff --git a/opentelemetry-otlp/src/proto/grpcio/trace_service.rs b/opentelemetry-otlp/src/proto/grpcio/trace_service.rs index 6ce4e359c8..8a154361bb 100644 --- a/opentelemetry-otlp/src/proto/grpcio/trace_service.rs +++ b/opentelemetry-otlp/src/proto/grpcio/trace_service.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.23.0. Do not edit +// This file is generated by rust-protobuf 2.24.1. Do not edit // @generated // https://github.com/rust-lang/rust-clippy/issues/702 @@ -21,7 +21,7 @@ /// Generated files are compatible only with the same version /// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_24_1; #[derive(PartialEq,Clone,Default)] #[cfg_attr(feature = "with-serde", derive(::serde::Serialize, ::serde::Deserialize))] diff --git a/opentelemetry/src/sdk/mod.rs b/opentelemetry/src/sdk/mod.rs index 24fa9a0764..83ea3f2148 100644 --- a/opentelemetry/src/sdk/mod.rs +++ b/opentelemetry/src/sdk/mod.rs @@ -6,7 +6,6 @@ //! facilitates the delivery of telemetry data to storage systems //! through `Exporter`s. These can be configured on `Tracer` and //! `Meter` creation. -pub mod env; pub mod export; pub mod instrumentation; #[cfg(feature = "metrics")] @@ -20,6 +19,5 @@ pub mod resource; #[cfg_attr(docsrs, doc(cfg(feature = "trace")))] pub mod trace; -pub use env::EnvResourceDetector; pub use instrumentation::InstrumentationLibrary; pub use resource::Resource; diff --git a/opentelemetry/src/sdk/env.rs b/opentelemetry/src/sdk/resource/env.rs similarity index 93% rename from opentelemetry/src/sdk/env.rs rename to opentelemetry/src/sdk/resource/env.rs index ccbef94044..a5abd2fa1e 100644 --- a/opentelemetry/src/sdk/env.rs +++ b/opentelemetry/src/sdk/resource/env.rs @@ -1,4 +1,4 @@ -//! EnvResourceDetector +//! Environment variables resource detector //! //! Implementation of `ResourceDetector` to extract a `Resource` from environment //! variables. @@ -59,9 +59,8 @@ fn construct_otel_resources(s: String) -> Resource { #[cfg(test)] mod tests { - use crate::sdk::env::OTEL_RESOURCE_ATTRIBUTES; - use crate::sdk::resource::{Resource, ResourceDetector}; - use crate::sdk::EnvResourceDetector; + use crate::sdk::resource::env::OTEL_RESOURCE_ATTRIBUTES; + use crate::sdk::resource::{EnvResourceDetector, Resource, ResourceDetector}; use crate::KeyValue; use std::{env, time}; diff --git a/opentelemetry/src/sdk/resource.rs b/opentelemetry/src/sdk/resource/mod.rs similarity index 93% rename from opentelemetry/src/sdk/resource.rs rename to opentelemetry/src/sdk/resource/mod.rs index a04d921777..52b8538c08 100644 --- a/opentelemetry/src/sdk/resource.rs +++ b/opentelemetry/src/sdk/resource/mod.rs @@ -13,9 +13,25 @@ //! produced by any `Tracer` from the provider are associated with this `Resource`. //! //! [`TracerProvider`]: crate::trace::TracerProvider +//! +//! # Resource detectors +//! +//! `ResourceDetector`s are used to detect resource from runtime or environmental variables. The +//! following `ResourceDetector`s are provided along with this SDK. +//! +//! - EnvResourceDetector, detect resource from environmental variables. +//! - OsResourceDetector, detect OS from runtime. +//! - ProcessResourceDetector, detect process information +mod env; +mod os; +mod process; + +pub use env::EnvResourceDetector; +pub use os::OsResourceDetector; +pub use process::ProcessResourceDetector; + #[cfg(feature = "metrics")] use crate::labels; -use crate::sdk::EnvResourceDetector; use crate::{Key, KeyValue, Value}; #[cfg(feature = "serialize")] use serde::{Deserialize, Serialize}; @@ -187,7 +203,7 @@ pub trait ResourceDetector { #[cfg(test)] mod tests { use super::*; - use crate::sdk::EnvResourceDetector; + use crate::sdk::resource::EnvResourceDetector; use std::collections::BTreeMap; use std::{env, time}; diff --git a/opentelemetry/src/sdk/resource/os.rs b/opentelemetry/src/sdk/resource/os.rs new file mode 100644 index 0000000000..f47197060b --- /dev/null +++ b/opentelemetry/src/sdk/resource/os.rs @@ -0,0 +1,46 @@ +//! OS resource detector +//! +//! Detect the runtime operating system type. +use crate::sdk::resource::ResourceDetector; +use crate::sdk::Resource; +use crate::KeyValue; +use std::env::consts::OS; +use std::time::Duration; + +/// Detect runtime operating system information. +/// +/// This detector uses Rust's [`OS constant`] to detect the operating system type and +/// maps the result to the supported value defined in [`OpenTelemetry spec`]. +/// +/// [`OS constant`]: https://doc.rust-lang.org/std/env/consts/constant.OS.html +/// [`OpenTelemetry spec`]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/os.md +#[derive(Debug)] +pub struct OsResourceDetector; + +impl ResourceDetector for OsResourceDetector { + fn detect(&self, _timeout: Duration) -> Resource { + Resource::new(vec![KeyValue::new("os.type", OS)]) + } +} + +#[cfg(test)] +mod tests { + use crate::sdk::resource::os::OsResourceDetector; + use crate::sdk::resource::ResourceDetector; + use crate::Key; + use std::time::Duration; + + #[cfg(target_os = "linux")] + #[test] + fn test_os_resource_detector() { + let resource = OsResourceDetector.detect(Duration::from_secs(0)); + assert_eq!( + resource + .iter() + .0 + .find(|(k, _v)| **k == Key::from_static_str("os.type")) + .map(|(_k, v)| v.to_string()), + Some("linux".to_string()) + ); + } +} diff --git a/opentelemetry/src/sdk/resource/process.rs b/opentelemetry/src/sdk/resource/process.rs new file mode 100644 index 0000000000..e5329efe8b --- /dev/null +++ b/opentelemetry/src/sdk/resource/process.rs @@ -0,0 +1,51 @@ +//! Process resource detector +//! +//! Detect process related information like pid, executable name. + +use crate::sdk::resource::ResourceDetector; +use crate::sdk::Resource; +use crate::{Array, KeyValue, Value}; +use std::borrow::Cow; +use std::env::args_os; +use std::process::id; +use std::time::Duration; + +/// Detect process information. +/// +/// This resource detector returns the following information: +/// +/// - process command line arguments(`process.command_args`), the full command arguments of this +/// application. +/// - OS assigned process id(`process.pid`). +#[derive(Debug)] +pub struct ProcessResourceDetector; + +impl ResourceDetector for ProcessResourceDetector { + fn detect(&self, _timeout: Duration) -> Resource { + let arguments = args_os(); + let cmd_arg_val = arguments + .into_iter() + .map(|arg| Cow::from(arg.to_string_lossy().into_owned())) + .collect::>>(); + Resource::new(vec![ + KeyValue::new( + "process.command_args", + Value::Array(Array::String(cmd_arg_val)), + ), + KeyValue::new("process.pid", id() as i64), + ]) + } +} + +#[cfg(test)] +mod tests { + use crate::sdk::resource::{ProcessResourceDetector, ResourceDetector}; + use std::time::Duration; + + #[cfg(target_os = "linux")] + #[test] + fn test_processor_resource_detector() { + let resource = ProcessResourceDetector.detect(Duration::from_secs(0)); + assert_eq!(resource.len(), 2); // we cannot assert on the values because it changes along with runtime. + } +}