From c775ada56497a0b8f5ca3df1aa560076a3e3f857 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 27 Dec 2024 11:02:38 -0800 Subject: [PATCH] Minor cleanup in Stdout exporter --- Cargo.toml | 1 - opentelemetry-stdout/CHANGELOG.md | 3 + opentelemetry-stdout/Cargo.toml | 2 - opentelemetry-stdout/src/common.rs | 306 ----------------------------- opentelemetry-stdout/src/lib.rs | 6 - 5 files changed, 3 insertions(+), 315 deletions(-) delete mode 100644 opentelemetry-stdout/src/common.rs diff --git a/Cargo.toml b/Cargo.toml index 99d8906132..1445047825 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,6 @@ hyper = { version = "1.3", default-features = false } hyper-util = "0.1" log = "0.4.21" once_cell = "1.13" -ordered-float = "4.0" pin-project-lite = "0.2" prost = "0.13" prost-build = "0.13" diff --git a/opentelemetry-stdout/CHANGELOG.md b/opentelemetry-stdout/CHANGELOG.md index 046262458d..ff0caf40ba 100644 --- a/opentelemetry-stdout/CHANGELOG.md +++ b/opentelemetry-stdout/CHANGELOG.md @@ -4,6 +4,9 @@ - Bump msrv to 1.75.0. - *Breaking* time fields, `StartTime` and `EndTime` is printed on aggregation (Sum, Gauge, Histogram, ExpoHistogram) with 2 tabs, previously it was on aggregation data point, with 3 tabs, see [#2377](https://github.com/open-telemetry/opentelemetry-rust/pull/2377) and [#2411](https://github.com/open-telemetry/opentelemetry-rust/pull/2411). +- Removed unused dependency on `ordered-float`. +- Feature flag "populate-logs-event-name" is removed as no longer relevant. + LogRecord's `event_name()` is now automatically displayed. ## 0.27.0 diff --git a/opentelemetry-stdout/Cargo.toml b/opentelemetry-stdout/Cargo.toml index 7061a5831b..800bdac140 100644 --- a/opentelemetry-stdout/Cargo.toml +++ b/opentelemetry-stdout/Cargo.toml @@ -24,7 +24,6 @@ default = ["trace", "metrics", "logs"] trace = ["opentelemetry/trace", "opentelemetry_sdk/trace", "futures-util"] metrics = ["async-trait", "opentelemetry/metrics", "opentelemetry_sdk/metrics"] logs = ["opentelemetry/logs", "opentelemetry_sdk/logs", "async-trait", "thiserror", "opentelemetry_sdk/spec_unstable_logs_enabled"] -populate-logs-event-name = [] [dependencies] async-trait = { workspace = true, optional = true } @@ -34,7 +33,6 @@ futures-util = { workspace = true, optional = true } opentelemetry = { version = "0.27", path = "../opentelemetry" } opentelemetry_sdk = { version = "0.27", path = "../opentelemetry-sdk" } serde = { workspace = true, features = ["derive"] } -ordered-float = { workspace = true } [dev-dependencies] opentelemetry = { path = "../opentelemetry", features = ["metrics"] } diff --git a/opentelemetry-stdout/src/common.rs b/opentelemetry-stdout/src/common.rs deleted file mode 100644 index 4da706f893..0000000000 --- a/opentelemetry-stdout/src/common.rs +++ /dev/null @@ -1,306 +0,0 @@ -use std::{ - borrow::Cow, - collections::BTreeMap, - hash::{Hash, Hasher}, - time::{SystemTime, UNIX_EPOCH}, -}; - -use chrono::{LocalResult, TimeZone, Utc}; -use ordered_float::OrderedFloat; -use serde::{Serialize, Serializer}; - -#[derive(Debug, Serialize, Clone, Hash, Eq, PartialEq)] -pub(crate) struct AttributeSet(pub BTreeMap); - -impl From<&opentelemetry_sdk::Resource> for AttributeSet { - fn from(value: &opentelemetry_sdk::Resource) -> Self { - AttributeSet( - value - .iter() - .map(|(key, value)| (Key::from(key.clone()), Value::from(value.clone()))) - .collect(), - ) - } -} - -#[derive(Debug, Clone, Serialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct Resource { - attributes: Vec, - #[serde(skip_serializing_if = "is_zero")] - dropped_attributes_count: u64, -} - -fn is_zero(v: &u64) -> bool { - *v == 0 -} - -impl From<&opentelemetry_sdk::Resource> for Resource { - fn from(value: &opentelemetry_sdk::Resource) -> Self { - Resource { - attributes: value - .iter() - .map(|(key, value)| KeyValue { - key: key.clone().into(), - value: value.clone().into(), - }) - .collect(), - dropped_attributes_count: 0, - } - } -} - -#[derive(Debug, Clone, Serialize, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub(crate) struct Key(Cow<'static, str>); - -impl From> for Key { - fn from(value: Cow<'static, str>) -> Self { - Key(value) - } -} - -impl From for Key { - fn from(value: opentelemetry::Key) -> Self { - Key(value.as_str().to_string().into()) - } -} - -#[derive(Debug, Serialize, Clone)] -#[allow(dead_code, clippy::enum_variant_names)] // we want to emphasize the *Values are collection -pub(crate) enum Value { - #[serde(rename = "boolValue")] - Bool(bool), - #[serde(rename = "intValue")] - Int(i64), - #[serde(rename = "doubleValue")] - Double(f64), - #[serde(rename = "stringValue")] - String(String), - #[serde(rename = "arrayValue")] - Array(Vec), - #[serde(rename = "kvListValue")] - KeyValues(Vec), - #[serde(rename = "bytesValue")] - BytesValue(Vec), -} - -impl PartialEq for Value { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Value::Bool(b), Value::Bool(ob)) => b.eq(ob), - (Value::Int(i), Value::Int(oi)) => i.eq(oi), - (Value::Double(f), Value::Double(of)) => OrderedFloat(*f).eq(&OrderedFloat(*of)), - (Value::String(s), Value::String(os)) => s.eq(os), - (Value::Array(a), Value::Array(oa)) => a.eq(oa), - (Value::KeyValues(kv), Value::KeyValues(okv)) => kv.eq(okv), - (Value::BytesValue(b), Value::BytesValue(ob)) => b.eq(ob), - (Value::Bool(_), _) => false, - (Value::Int(_), _) => false, - (Value::Double(_), _) => false, - (Value::String(_), _) => false, - (Value::Array(_), _) => false, - (Value::KeyValues(_), _) => false, - (Value::BytesValue(_), _) => false, - } - } -} - -impl Eq for Value {} - -impl Hash for Value { - fn hash(&self, state: &mut H) { - match &self { - Value::Bool(b) => b.hash(state), - Value::Int(i) => i.hash(state), - Value::Double(f) => OrderedFloat(*f).hash(state), - Value::String(s) => s.hash(state), - Value::Array(a) => a.iter().for_each(|v| v.hash(state)), - Value::KeyValues(kv) => kv.iter().for_each(|kv| { - kv.key.hash(state); - kv.value.hash(state); - }), - Value::BytesValue(b) => b.hash(state), - } - } -} - -impl From for Value { - fn from(value: opentelemetry::Value) -> Self { - match value { - opentelemetry::Value::Bool(b) => Value::Bool(b), - opentelemetry::Value::I64(i) => Value::Int(i), - opentelemetry::Value::F64(f) => Value::Double(f), - opentelemetry::Value::String(s) => Value::String(s.into()), - opentelemetry::Value::Array(a) => match a { - opentelemetry::Array::Bool(b) => { - Value::Array(b.into_iter().map(Value::Bool).collect()) - } - opentelemetry::Array::I64(i) => { - Value::Array(i.into_iter().map(Value::Int).collect()) - } - opentelemetry::Array::F64(f) => { - Value::Array(f.into_iter().map(Value::Double).collect()) - } - opentelemetry::Array::String(s) => { - Value::Array(s.into_iter().map(|s| Value::String(s.into())).collect()) - } - _ => unreachable!("Nonexistent array type"), // Needs to be updated when new array types are added - }, - _ => unreachable!("Nonexistent value type"), // Needs to be updated when new value types are added - } - } -} - -#[cfg(feature = "logs")] -impl From for Value { - fn from(value: opentelemetry::logs::AnyValue) -> Self { - match value { - opentelemetry::logs::AnyValue::Boolean(b) => Value::Bool(b), - opentelemetry::logs::AnyValue::Int(i) => Value::Int(i), - opentelemetry::logs::AnyValue::Double(d) => Value::Double(d), - opentelemetry::logs::AnyValue::String(s) => Value::String(s.into()), - opentelemetry::logs::AnyValue::ListAny(a) => { - Value::Array(a.into_iter().map(Into::into).collect()) - } - opentelemetry::logs::AnyValue::Map(m) => Value::KeyValues( - m.into_iter() - .map(|(key, value)| KeyValue { - key: key.into(), - value: value.into(), - }) - .collect(), - ), - opentelemetry::logs::AnyValue::Bytes(b) => Value::BytesValue(*b), - _ => unreachable!("Nonexistent value type"), - } - } -} - -#[derive(Debug, Serialize, PartialEq, Clone)] -#[serde(rename_all = "camelCase")] -pub(crate) struct KeyValue { - key: Key, - value: Value, -} - -#[cfg(feature = "logs")] -impl From<(opentelemetry::Key, opentelemetry::logs::AnyValue)> for KeyValue { - fn from((key, value): (opentelemetry::Key, opentelemetry::logs::AnyValue)) -> Self { - KeyValue { - key: key.into(), - value: value.into(), - } - } -} - -impl From for KeyValue { - fn from(value: opentelemetry::KeyValue) -> Self { - KeyValue { - key: value.key.into(), - value: value.value.into(), - } - } -} - -impl From<&opentelemetry::KeyValue> for KeyValue { - fn from(value: &opentelemetry::KeyValue) -> Self { - KeyValue { - key: value.key.clone().into(), - value: value.value.clone().into(), - } - } -} - -impl From<(opentelemetry::Key, opentelemetry::Value)> for KeyValue { - fn from((key, value): (opentelemetry::Key, opentelemetry::Value)) -> Self { - KeyValue { - key: key.into(), - value: value.into(), - } - } -} - -#[derive(Debug, Clone, Serialize, PartialEq)] -#[serde(rename_all = "camelCase")] -pub(crate) struct Scope { - #[serde(skip_serializing_if = "str::is_empty")] - name: Cow<'static, str>, - #[serde(skip_serializing_if = "Option::is_none")] - version: Option>, - #[serde(skip_serializing_if = "Vec::is_empty")] - attributes: Vec, - #[serde(skip_serializing_if = "is_zero")] - dropped_attributes_count: u64, -} - -impl From for Scope { - fn from(value: opentelemetry::InstrumentationScope) -> Self { - Scope { - name: value.name().to_owned().into(), - version: value.version().map(ToOwned::to_owned).map(Into::into), - attributes: value.attributes().map(Into::into).collect(), - dropped_attributes_count: 0, - } - } -} - -pub(crate) fn as_human_readable(time: &SystemTime, serializer: S) -> Result -where - S: Serializer, -{ - let duration_since_epoch = time.duration_since(UNIX_EPOCH).unwrap_or_default(); - - match Utc.timestamp_opt( - duration_since_epoch.as_secs() as i64, - duration_since_epoch.subsec_nanos(), - ) { - LocalResult::Single(datetime) => serializer.serialize_str( - datetime - .format("%Y-%m-%d %H:%M:%S.%3f") - .to_string() - .as_ref(), - ), - _ => Err(serde::ser::Error::custom("Invalid Timestamp.")), - } -} - -#[allow(dead_code)] -// Used for serde serialization. Not used in traces. -pub(crate) fn as_opt_human_readable( - time: &Option, - serializer: S, -) -> Result -where - S: Serializer, -{ - match time { - None => serializer.serialize_none(), - Some(time) => as_human_readable(time, serializer), - } -} - -pub(crate) fn as_unix_nano(time: &SystemTime, serializer: S) -> Result -where - S: Serializer, -{ - let nanos = time - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_nanos(); - - serializer.serialize_u128(nanos) -} - -#[allow(dead_code)] -pub(crate) fn as_opt_unix_nano( - time: &Option, - serializer: S, -) -> Result -where - S: Serializer, -{ - match time { - None => serializer.serialize_none(), - Some(time) => as_unix_nano(time, serializer), - } -} diff --git a/opentelemetry-stdout/src/lib.rs b/opentelemetry-stdout/src/lib.rs index 207eb1460c..6821ad8db4 100644 --- a/opentelemetry-stdout/src/lib.rs +++ b/opentelemetry-stdout/src/lib.rs @@ -11,10 +11,6 @@ //! * `metrics`: Includes the metrics exporters. //! * `logs`: Includes the logs exporters. //! -//! The following feature flags generate additional code and types: -//! * `populate-logs-event-name`: Enables sending `LogRecord::event_name` as an attribute -//! with the key `name` -//! //! # Examples //! //! ```no_run @@ -64,8 +60,6 @@ deny(rustdoc::broken_intra_doc_links) )] -pub(crate) mod common; - #[cfg(feature = "metrics")] mod metrics; #[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]