Skip to content

Commit

Permalink
Merge branch 'main' into logrecord-getters
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Nov 21, 2024
2 parents 29474f4 + 465fcc2 commit 4507e16
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 67 deletions.
3 changes: 3 additions & 0 deletions opentelemetry-proto/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## vNext

- Update proto definitions to v1.4.0 [#2315](https://github.com/open-telemetry/opentelemetry-rust/pull/2315)


## 0.27.0

Released 2024-Nov-11
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@
/// storage, OR can be embedded by other protocols that transfer OTLP metrics
/// data but do not implement the OTLP protocol.
///
/// MetricsData
/// └─── ResourceMetrics
/// ├── Resource
/// ├── SchemaURL
/// └── ScopeMetrics
/// ├── Scope
/// ├── SchemaURL
/// └── Metric
/// ├── Name
/// ├── Description
/// ├── Unit
/// └── data
/// ├── Gauge
/// ├── Sum
/// ├── Histogram
/// ├── ExponentialHistogram
/// └── Summary
///
/// The main difference between this message and collector protocol is that
/// in this message there will not be any "control" or "metadata" specific to
/// OTLP protocol.
Expand Down Expand Up @@ -71,7 +89,6 @@ pub struct ScopeMetrics {
///
/// <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md>
///
///
/// The data model and relation between entities is shown in the
/// diagram below. Here, "DataPoint" is the term used to refer to any
/// one of the specific data point value types, and "points" is the term used
Expand All @@ -83,7 +100,7 @@ pub struct ScopeMetrics {
/// - DataPoint contains timestamps, attributes, and one of the possible value type
/// fields.
///
/// Metric
/// Metric
/// +------------+
/// |name |
/// |description |
Expand Down Expand Up @@ -277,6 +294,9 @@ pub struct ExponentialHistogram {
/// data type. These data points cannot always be merged in a meaningful way.
/// While they can be useful in some applications, histogram data points are
/// recommended for new applications.
/// Summary metrics do not have an aggregation temporality field. This is
/// because the count and sum fields of a SummaryDataPoint are assumed to be
/// cumulative values.
#[cfg_attr(feature = "with-schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "with-serde", serde(rename_all = "camelCase"))]
Expand Down Expand Up @@ -587,7 +607,8 @@ pub mod exponential_histogram_data_point {
}
}
/// SummaryDataPoint is a single data point in a timeseries that describes the
/// time-varying values of a Summary metric.
/// time-varying values of a Summary metric. The count and sum fields represent
/// cumulative values.
#[cfg_attr(feature = "with-schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "with-serde", serde(rename_all = "camelCase"))]
Expand Down
2 changes: 1 addition & 1 deletion opentelemetry-sdk/benches/metrics_counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
|--------------------------------|-------------|
| Counter_Add_Sorted | 172 ns |
| Counter_Add_Unsorted | 183 ns |
| Counter_Overflow | 898 ns |
| Counter_Overflow | 562 ns |
| ThreadLocal_Random_Generator_5 | 37 ns |
*/

Expand Down
14 changes: 11 additions & 3 deletions opentelemetry-sdk/src/metrics/internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ pub(crate) use exponential_histogram::{EXPO_MAX_SCALE, EXPO_MIN_SCALE};
use once_cell::sync::Lazy;
use opentelemetry::{otel_warn, KeyValue};

use crate::metrics::AttributeSet;

pub(crate) static STREAM_OVERFLOW_ATTRIBUTES: Lazy<Vec<KeyValue>> =
Lazy::new(|| vec![KeyValue::new("otel.metric.overflow", "true")]);

Expand Down Expand Up @@ -95,7 +93,7 @@ where
}

// Try to retrieve and update the tracker with the attributes sorted.
let sorted_attrs = AttributeSet::from(attributes).into_vec();
let sorted_attrs = sort_and_dedup(attributes);
if let Some(tracker) = trackers.get(sorted_attrs.as_slice()) {
tracker.update(value);
return;
Expand Down Expand Up @@ -198,6 +196,16 @@ fn prepare_data<T>(data: &mut Vec<T>, list_len: usize) {
}
}

fn sort_and_dedup(attributes: &[KeyValue]) -> Vec<KeyValue> {
// Use newly allocated vec here as incoming attributes are immutable so
// cannot sort/de-dup in-place. TODO: This allocation can be avoided by
// leveraging a ThreadLocal vec.
let mut sorted = attributes.to_vec();
sorted.sort_unstable_by(|a, b| a.key.cmp(&b.key));
sorted.dedup_by(|a, b| a.key == b.key);
sorted
}

/// Marks a type that can have a value added and retrieved atomically. Required since
/// different types have different backing atomic mechanisms
pub(crate) trait AtomicTracker<T>: Sync + Send + 'static {
Expand Down
60 changes: 1 addition & 59 deletions opentelemetry-sdk/src/metrics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,7 @@ pub use view::*;
// #[cfg(not(feature = "spec_unstable_metrics_views"))]
// pub(crate) use view::*;

use std::collections::hash_map::DefaultHasher;
use std::collections::HashSet;
use std::hash::{Hash, Hasher};

use opentelemetry::KeyValue;
use std::hash::Hash;

/// Defines the window that an aggregation was calculated over.
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)]
Expand All @@ -106,60 +102,6 @@ pub enum Temporality {
LowMemory,
}

/// A unique set of attributes that can be used as instrument identifiers.
///
/// This must implement [Hash], [PartialEq], and [Eq] so it may be used as
/// HashMap keys and other de-duplication methods.
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub(crate) struct AttributeSet(Vec<KeyValue>, u64);

impl From<&[KeyValue]> for AttributeSet {
fn from(values: &[KeyValue]) -> Self {
let mut seen_keys = HashSet::with_capacity(values.len());
let vec = values
.iter()
.rev()
.filter_map(|kv| {
if seen_keys.insert(kv.key.clone()) {
Some(kv.clone())
} else {
None
}
})
.collect::<Vec<_>>();

AttributeSet::new(vec)
}
}

fn calculate_hash(values: &[KeyValue]) -> u64 {
let mut hasher = DefaultHasher::new();
values.iter().fold(&mut hasher, |mut hasher, item| {
item.hash(&mut hasher);
hasher
});
hasher.finish()
}

impl AttributeSet {
fn new(mut values: Vec<KeyValue>) -> Self {
values.sort_unstable_by(|a, b| a.key.cmp(&b.key));
let hash = calculate_hash(&values);
AttributeSet(values, hash)
}

/// Returns the underlying Vec of KeyValue pairs
pub(crate) fn into_vec(self) -> Vec<KeyValue> {
self.0
}
}

impl Hash for AttributeSet {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u64(self.1)
}
}

#[cfg(all(test, feature = "testing"))]
mod tests {
use self::data::{DataPoint, HistogramDataPoint, ScopeMetrics};
Expand Down

0 comments on commit 4507e16

Please sign in to comment.