Skip to content

Commit 62f1274

Browse files
authored
Merge branch 'main' into baggage-improvements
2 parents 1d987fe + a707bb9 commit 62f1274

File tree

9 files changed

+127
-149
lines changed

9 files changed

+127
-149
lines changed

opentelemetry-otlp/CHANGELOG.md

+19-15
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,6 @@
22

33
## vNext
44

5-
## v0.26.0
6-
Released 2024-Sep-30
7-
8-
- Update `opentelemetry` dependency version to 0.26
9-
- Update `opentelemetry_sdk` dependency version to 0.26
10-
- Update `opentelemetry-http` dependency version to 0.26
11-
- Update `opentelemetry-proto` dependency version to 0.26
12-
- Bump MSRV to 1.71.1 [2140](https://github.com/open-telemetry/opentelemetry-rust/pull/2140)
135
- **BREAKING**:
146
- ([#2217](https://github.com/open-telemetry/opentelemetry-rust/pull/2217)) **Replaced**: The `MetricsExporterBuilder` interface is modified from `with_temporality_selector` to `with_temporality` example can be seen below:
157
Previous Signature:
@@ -31,6 +23,7 @@ Released 2024-Sep-30
3123
```rust
3224
let logger_provider: LoggerProvider = opentelemetry_otlp::new_pipeline()
3325
.logging()
26+
.with_resource(RESOURCE.clone())
3427
.with_exporter(
3528
opentelemetry_otlp::new_exporter()
3629
.tonic()
@@ -40,13 +33,15 @@ Released 2024-Sep-30
4033
```
4134
Updated Signature:
4235
```rust
43-
let logger_provider: LoggerProvider = LoggerProvider::builder()
44-
.install_batch_exporter(
45-
LogExporter::builder()
46-
.with_tonic()
47-
.with_endpoint("http://localhost:4317")
48-
.build()?,
49-
).build();
36+
let exporter = LogExporter::builder()
37+
.with_tonic()
38+
.with_endpoint("http://localhost:4317")
39+
.build()?;
40+
41+
Ok(LoggerProvider::builder()
42+
.with_resource(RESOURCE.clone())
43+
.with_batch_exporter(exporter, runtime::Tokio)
44+
.build())
5045
```
5146
- **Renamed**
5247
- ([#2255](https://github.com/open-telemetry/opentelemetry-rust/pull/2255)): de-pluralize Metric types.
@@ -56,6 +51,15 @@ Released 2024-Sep-30
5651
- [#2263](https://github.com/open-telemetry/opentelemetry-rust/pull/2263)
5752
Support `hyper` client for opentelemetry-otlp. This can be enabled using flag `hyper-client`.
5853
Refer example: https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-otlp/examples/basic-otlp-http
54+
55+
## v0.26.0
56+
Released 2024-Sep-30
57+
58+
- Update `opentelemetry` dependency version to 0.26
59+
- Update `opentelemetry_sdk` dependency version to 0.26
60+
- Update `opentelemetry-http` dependency version to 0.26
61+
- Update `opentelemetry-proto` dependency version to 0.26
62+
- Bump MSRV to 1.71.1 [2140](https://github.com/open-telemetry/opentelemetry-rust/pull/2140)
5963

6064
## v0.25.0
6165

opentelemetry-sdk/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
- Bump MSRV to 1.70 [#2179](https://github.com/open-telemetry/opentelemetry-rust/pull/2179)
66
- Implement `LogRecord::set_trace_context` for `LogRecord`. Respect any trace context set on a `LogRecord` when emitting through a `Logger`.
77
- Improved `LoggerProvider` shutdown handling to prevent redundant shutdown calls when `drop` is invoked. [#2195](https://github.com/open-telemetry/opentelemetry-rust/pull/2195)
8-
- When creating new metric instruments, SDK would return a no-op instrument if the validation fails. [#2166](https://github.com/open-telemetry/opentelemetry-rust/pull/2166)
8+
- When creating new metric instruments by calling `build()`, SDK would return a no-op instrument if the validation fails (eg: Invalid metric name). [#2166](https://github.com/open-telemetry/opentelemetry-rust/pull/2166)
99
- **BREAKING for Metrics users**:
1010
- **Replaced**
1111
- ([#2217](https://github.com/open-telemetry/opentelemetry-rust/pull/2217)): Removed `{Delta,Cumulative}TemporalitySelector::new()` in favor of directly using `Temporality` enum to simplify the configuration of MetricsExporterBuilder with different temporalities.

opentelemetry-sdk/src/metrics/internal/histogram.rs

+46-125
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ use opentelemetry::KeyValue;
99
use super::ValueMap;
1010
use super::{Aggregator, Number};
1111

12-
struct HistogramTracker<T> {
13-
buckets: Mutex<Buckets<T>>,
14-
}
15-
16-
impl<T> Aggregator for HistogramTracker<T>
12+
impl<T> Aggregator for Mutex<Buckets<T>>
1713
where
1814
T: Number,
1915
{
@@ -22,27 +18,26 @@ where
2218
type PreComputedValue = (T, usize);
2319

2420
fn update(&self, (value, index): (T, usize)) {
25-
let mut buckets = match self.buckets.lock() {
26-
Ok(guard) => guard,
27-
Err(_) => return,
28-
};
21+
let mut buckets = self.lock().unwrap_or_else(|err| err.into_inner());
2922

30-
buckets.bin(index, value);
31-
buckets.sum(value);
23+
buckets.total += value;
24+
buckets.count += 1;
25+
buckets.counts[index] += 1;
26+
if value < buckets.min {
27+
buckets.min = value;
28+
}
29+
if value > buckets.max {
30+
buckets.max = value
31+
}
3232
}
3333

3434
fn create(count: &usize) -> Self {
35-
HistogramTracker {
36-
buckets: Mutex::new(Buckets::<T>::new(*count)),
37-
}
35+
Mutex::new(Buckets::<T>::new(*count))
3836
}
3937

4038
fn clone_and_reset(&self, count: &usize) -> Self {
41-
let mut current = self.buckets.lock().unwrap_or_else(|err| err.into_inner());
42-
let cloned = replace(current.deref_mut(), Buckets::new(*count));
43-
Self {
44-
buckets: Mutex::new(cloned),
45-
}
39+
let mut current = self.lock().unwrap_or_else(|err| err.into_inner());
40+
Mutex::new(replace(current.deref_mut(), Buckets::new(*count)))
4641
}
4742
}
4843

@@ -65,62 +60,34 @@ impl<T: Number> Buckets<T> {
6560
..Default::default()
6661
}
6762
}
68-
69-
fn sum(&mut self, value: T) {
70-
self.total += value;
71-
}
72-
73-
fn bin(&mut self, idx: usize, value: T) {
74-
self.counts[idx] += 1;
75-
self.count += 1;
76-
if value < self.min {
77-
self.min = value;
78-
}
79-
if value > self.max {
80-
self.max = value
81-
}
82-
}
8363
}
8464

8565
/// Summarizes a set of measurements as a histogram with explicitly defined
8666
/// buckets.
8767
pub(crate) struct Histogram<T: Number> {
88-
value_map: ValueMap<HistogramTracker<T>>,
68+
value_map: ValueMap<Mutex<Buckets<T>>>,
8969
bounds: Vec<f64>,
9070
record_min_max: bool,
9171
record_sum: bool,
9272
start: Mutex<SystemTime>,
9373
}
9474

9575
impl<T: Number> Histogram<T> {
96-
pub(crate) fn new(boundaries: Vec<f64>, record_min_max: bool, record_sum: bool) -> Self {
97-
// TODO fix the bug, by first removing NaN and only then getting buckets_count
98-
// once we know the reason for performance degradation
99-
let buckets_count = boundaries.len() + 1;
100-
let mut histogram = Histogram {
76+
pub(crate) fn new(mut bounds: Vec<f64>, record_min_max: bool, record_sum: bool) -> Self {
77+
bounds.retain(|v| !v.is_nan());
78+
bounds.sort_by(|a, b| a.partial_cmp(b).expect("NaNs filtered out"));
79+
let buckets_count = bounds.len() + 1;
80+
Histogram {
10181
value_map: ValueMap::new(buckets_count),
102-
bounds: boundaries,
82+
bounds,
10383
record_min_max,
10484
record_sum,
10585
start: Mutex::new(SystemTime::now()),
106-
};
107-
108-
histogram.bounds.retain(|v| !v.is_nan());
109-
histogram
110-
.bounds
111-
.sort_by(|a, b| a.partial_cmp(b).expect("NaNs filtered out"));
112-
113-
histogram
86+
}
11487
}
11588

11689
pub(crate) fn measure(&self, measurement: T, attrs: &[KeyValue]) {
11790
let f = measurement.into_float();
118-
// Ignore NaN and infinity.
119-
// Only makes sense if T is f64, maybe this could be no-op for other cases?
120-
// TODO: uncomment once we know the reason for performance degradation
121-
// if f.is_infinite() || f.is_nan() {
122-
// return;
123-
// }
12491
// This search will return an index in the range `[0, bounds.len()]`, where
12592
// it will return `bounds.len()` if value is greater than the last element
12693
// of `bounds`. This aligns with the buckets in that the length of buckets
@@ -156,17 +123,14 @@ impl<T: Number> Histogram<T> {
156123

157124
self.value_map
158125
.collect_and_reset(&mut h.data_points, |attributes, aggr| {
159-
let b = aggr
160-
.buckets
161-
.into_inner()
162-
.unwrap_or_else(|err| err.into_inner());
126+
let b = aggr.into_inner().unwrap_or_else(|err| err.into_inner());
163127
HistogramDataPoint {
164128
attributes,
165129
start_time: prev_start,
166130
time: t,
167131
count: b.count,
168132
bounds: self.bounds.clone(),
169-
bucket_counts: b.counts.clone(),
133+
bucket_counts: b.counts,
170134
sum: if self.record_sum {
171135
b.total
172136
} else {
@@ -214,7 +178,7 @@ impl<T: Number> Histogram<T> {
214178

215179
self.value_map
216180
.collect_readonly(&mut h.data_points, |attributes, aggr| {
217-
let b = aggr.buckets.lock().unwrap_or_else(|err| err.into_inner());
181+
let b = aggr.lock().unwrap_or_else(|err| err.into_inner());
218182
HistogramDataPoint {
219183
attributes,
220184
start_time: prev_start,
@@ -245,68 +209,25 @@ impl<T: Number> Histogram<T> {
245209
}
246210
}
247211

248-
// TODO: uncomment once we know the reason for performance degradation
249-
// #[cfg(test)]
250-
// mod tests {
212+
#[cfg(test)]
213+
mod tests {
214+
use super::*;
251215

252-
// use super::*;
253-
254-
// #[test]
255-
// fn when_f64_is_nan_or_infinity_then_ignore() {
256-
// struct Expected {
257-
// min: f64,
258-
// max: f64,
259-
// sum: f64,
260-
// count: u64,
261-
// }
262-
// impl Expected {
263-
// fn new(min: f64, max: f64, sum: f64, count: u64) -> Self {
264-
// Expected {
265-
// min,
266-
// max,
267-
// sum,
268-
// count,
269-
// }
270-
// }
271-
// }
272-
// struct TestCase {
273-
// values: Vec<f64>,
274-
// expected: Expected,
275-
// }
276-
277-
// let test_cases = vec![
278-
// TestCase {
279-
// values: vec![2.0, 4.0, 1.0],
280-
// expected: Expected::new(1.0, 4.0, 7.0, 3),
281-
// },
282-
// TestCase {
283-
// values: vec![2.0, 4.0, 1.0, f64::INFINITY],
284-
// expected: Expected::new(1.0, 4.0, 7.0, 3),
285-
// },
286-
// TestCase {
287-
// values: vec![2.0, 4.0, 1.0, -f64::INFINITY],
288-
// expected: Expected::new(1.0, 4.0, 7.0, 3),
289-
// },
290-
// TestCase {
291-
// values: vec![2.0, f64::NAN, 4.0, 1.0],
292-
// expected: Expected::new(1.0, 4.0, 7.0, 3),
293-
// },
294-
// TestCase {
295-
// values: vec![4.0, 4.0, 4.0, 2.0, 16.0, 1.0],
296-
// expected: Expected::new(1.0, 16.0, 31.0, 6),
297-
// },
298-
// ];
299-
300-
// for test in test_cases {
301-
// let h = Histogram::new(vec![], true, true);
302-
// for v in test.values {
303-
// h.measure(v, &[]);
304-
// }
305-
// let res = h.value_map.no_attribute_tracker.buckets.lock().unwrap();
306-
// assert_eq!(test.expected.max, res.max);
307-
// assert_eq!(test.expected.min, res.min);
308-
// assert_eq!(test.expected.sum, res.total);
309-
// assert_eq!(test.expected.count, res.count);
310-
// }
311-
// }
312-
// }
216+
#[test]
217+
fn check_buckets_are_selected_correctly() {
218+
let hist = Histogram::<i64>::new(vec![1.0, 3.0, 6.0], false, false);
219+
for v in 1..11 {
220+
hist.measure(v, &[]);
221+
}
222+
let (count, dp) = hist.cumulative(None);
223+
let dp = dp.unwrap();
224+
let dp = dp.as_any().downcast_ref::<data::Histogram<i64>>().unwrap();
225+
assert_eq!(count, 1);
226+
assert_eq!(dp.data_points[0].count, 10);
227+
assert_eq!(dp.data_points[0].bucket_counts.len(), 4);
228+
assert_eq!(dp.data_points[0].bucket_counts[0], 1); // 1
229+
assert_eq!(dp.data_points[0].bucket_counts[1], 2); // 2, 3
230+
assert_eq!(dp.data_points[0].bucket_counts[2], 3); // 4, 5, 6
231+
assert_eq!(dp.data_points[0].bucket_counts[3], 4); // 7, 8, 9, 10
232+
}
233+
}

opentelemetry/CHANGELOG.md

+6-8
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
- Introduced `SyncInstrument` trait to replace the individual synchronous instrument traits (`SyncCounter`, `SyncGauge`, `SyncHistogram`, `SyncUpDownCounter`) which are meant for SDK implementation. [#2207](https://github.com/open-telemetry/opentelemetry-rust/pull/2207)
99
- Ensured that `observe` method on asynchronous instruments can only be called inside a callback. This was done by removing the implementation of `AsyncInstrument` trait for each of the asynchronous instruments. [#2210](https://github.com/open-telemetry/opentelemetry-rust/pull/2210)
1010
- Removed `PartialOrd` and `Ord` implementations for `KeyValue`. [#2215](https://github.com/open-telemetry/opentelemetry-rust/pull/2215)
11-
- **Breaking change** Removed `try_init` methods from the instrument builders. Users should only use `init` method to create instruments. [#2227](https://github.com/open-telemetry/opentelemetry-rust/pull/2227)
12-
- Updated the return types of `InstrumentProvider` trait methods to return the instrument instead of a `Result`. [#2227](https://github.com/open-telemetry/opentelemetry-rust/pull/2227)
1311
- **Breaking change for exporter authors:** Marked `KeyValue` related structs and enums as `non_exhaustive`. [#2228](https://github.com/open-telemetry/opentelemetry-rust/pull/2228)
1412
- **Breaking change for log exporter authors:** Marked `AnyValue` enum as `non_exhaustive`. [#2230](https://github.com/open-telemetry/opentelemetry-rust/pull/2230)
15-
- **Breaking change for Metrics users:** The `init` method used to create instruments has been renamed to `build`.
13+
- **Breaking change for Metrics users:** The `init` method used to create instruments has been renamed to `build`. Also, `try_init()` method is removed from instrument builders. The return types of `InstrumentProvider` trait methods modified to return the instrument struct, instead of `Result`. [#2227](https://github.com/open-telemetry/opentelemetry-rust/pull/2227)
1614

1715
Before:
1816
```rust
@@ -32,16 +30,16 @@ let counter = meter.u64_counter("my_counter").build();
3230
- Replaced these methods with `LoggerProvider::logger_with_scope`, `TracerProvider::logger_with_scope`, `MeterProvider::meter_with_scope`
3331
- Replaced `global::meter_with_version` with `global::meter_with_scope`
3432
- Added `global::tracer_with_scope`
33+
- Refer to PR description for migration guide.
34+
- **Breaking change**: replaced `InstrumentationScope` public attributes by getters [#2275](https://github.com/open-telemetry/opentelemetry-rust/pull/2275)
3535

3636
- **Breaking change**: [#2260](https://github.com/open-telemetry/opentelemetry-rust/pull/2260)
3737
- Removed `global::set_error_handler` and `global::handle_error`.
3838
- `global::handle_error` usage inside the opentelemetry crates has been replaced with `global::otel_info`, `otel_warn`, `otel_debug` and `otel_error` macros based on the severity of the internal logs.
39-
- The default behavior of `global::handle_error` was to log the error using `eprintln!`. With otel macro, the internal logs get emitted via `tracing` macros of matching severity. Users now need to configure the `tracing` layer to capture these logs.
40-
- Refer to this PR description for migration guide. Also refer to [self-diagnostics](https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples/self-diagnostics) example on how to configure the tracing layer for internal logs.
41-
- **Breaking change**: replaced `InstrumentationScope` public attributes by getters [#2275](https://github.com/open-telemetry/opentelemetry-rust/pull/2275)
39+
- The default behavior of `global::handle_error` was to log the error using `eprintln!`. With otel macros, the internal logs get emitted via `tracing` macros of matching severity. Users now need to configure a `tracing` layer/subscriber to capture these logs.
40+
- Refer to PR description for migration guide. Also refer to [self-diagnostics](https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples/self-diagnostics) example to learn how to view internal logs in stdout using `tracing::fmt` layer.
4241

43-
44-
- [#2266](https://github.com/open-telemetry/opentelemetry-rust/pull/2266)
42+
- **Breaking change for exporter/processor authors:** [#2266](https://github.com/open-telemetry/opentelemetry-rust/pull/2266)
4543
- Moved `ExportError` trait from `opentelemetry::ExportError` to `opentelemetry_sdk::export::ExportError`
4644
- Created new trait `opentelemetry::trace::ExportError` for trace API. This would be eventually be consolidated with ExportError in the SDK.
4745
- Moved `LogError` enum from `opentelemetry::logs::LogError` to `opentelemetry_sdk::logs::LogError`

opentelemetry/src/metrics/instruments/counter.rs

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use std::sync::Arc;
55
use super::SyncInstrument;
66

77
/// An instrument that records increasing values.
8+
///
9+
/// [`Counter`] can be cloned to create multiple handles to the same instrument. If a [`Counter`] needs to be shared,
10+
/// users are recommended to clone the [`Counter`] instead of creating duplicate [`Counter`]s for the same metric. Creating
11+
/// duplicate [`Counter`]s for the same metric could lower SDK performance.
812
#[derive(Clone)]
913
#[non_exhaustive]
1014
pub struct Counter<T>(Arc<dyn SyncInstrument<T> + Send + Sync>);

opentelemetry/src/metrics/instruments/gauge.rs

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use std::sync::Arc;
55
use super::SyncInstrument;
66

77
/// An instrument that records independent values
8+
///
9+
/// [`Gauge`] can be cloned to create multiple handles to the same instrument. If a [`Gauge`] needs to be shared,
10+
/// users are recommended to clone the [`Gauge`] instead of creating duplicate [`Gauge`]s for the same metric. Creating
11+
/// duplicate [`Gauge`]s for the same metric could lower SDK performance.
812
#[derive(Clone)]
913
#[non_exhaustive]
1014
pub struct Gauge<T>(Arc<dyn SyncInstrument<T> + Send + Sync>);

opentelemetry/src/metrics/instruments/histogram.rs

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use std::sync::Arc;
55
use super::SyncInstrument;
66

77
/// An instrument that records a distribution of values.
8+
///
9+
/// [`Histogram`] can be cloned to create multiple handles to the same instrument. If a [`Histogram`] needs to be shared,
10+
/// users are recommended to clone the [`Histogram`] instead of creating duplicate [`Histogram`]s for the same metric. Creating
11+
/// duplicate [`Histogram`]s for the same metric could lower SDK performance.
812
#[derive(Clone)]
913
#[non_exhaustive]
1014
pub struct Histogram<T>(Arc<dyn SyncInstrument<T> + Send + Sync>);

opentelemetry/src/metrics/instruments/up_down_counter.rs

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use std::sync::Arc;
55
use super::SyncInstrument;
66

77
/// An instrument that records increasing or decreasing values.
8+
///
9+
/// [`UpDownCounter`] can be cloned to create multiple handles to the same instrument. If a [`UpDownCounter`] needs to be shared,
10+
/// users are recommended to clone the [`UpDownCounter`] instead of creating duplicate [`UpDownCounter`]s for the same metric. Creating
11+
/// duplicate [`UpDownCounter`]s for the same metric could lower SDK performance.
812
#[derive(Clone)]
913
#[non_exhaustive]
1014
pub struct UpDownCounter<T>(Arc<dyn SyncInstrument<T> + Send + Sync>);

0 commit comments

Comments
 (0)