Skip to content

Commit be897ff

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/chore/semantic-commits' into chore/semantic-commits
2 parents 6e3d81f + 9135bde commit be897ff

File tree

14 files changed

+279
-164
lines changed

14 files changed

+279
-164
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ you're more than welcome to participate!
186186
### Approvers
187187

188188
* [Shaun Cox](https://github.com/shaun-cox)
189+
* [Scott Gerring](https://github.com/scottgerring)
189190

190191
### Emeritus
191192

opentelemetry-otlp/CHANGELOG.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## vNext
44

55
- The `OTEL_EXPORTER_OTLP_TIMEOUT`, `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`, `OTEL_EXPORTER_OTLP_METRICS_TIMEOUT` and `OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` are changed from seconds to miliseconds.
6+
- Fixed `.with_headers()` in `HttpExporterBuilder` to correctly support multiple key/value pairs. [#2699](https://github.com/open-telemetry/opentelemetry-rust/pull/2699)
67

78
## 0.28.0
89

@@ -41,7 +42,7 @@ Released 2024-Nov-11
4142
- Update `opentelemetry-http` dependency version to 0.27
4243
- Update `opentelemetry-proto` dependency version to 0.27
4344

44-
- **BREAKING**:
45+
- **BREAKING**:
4546
- ([#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:
4647
Previous Signature:
4748
```rust
@@ -88,9 +89,9 @@ Released 2024-Nov-11
8889
- `MetricsExporterBuilder` -> `MetricExporterBuilder`
8990

9091
- [#2263](https://github.com/open-telemetry/opentelemetry-rust/pull/2263)
91-
Support `hyper` client for opentelemetry-otlp. This can be enabled using flag `hyper-client`.
92+
Support `hyper` client for opentelemetry-otlp. This can be enabled using flag `hyper-client`.
9293
Refer example: https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-otlp/examples/basic-otlp-http
93-
94+
9495
## v0.26.0
9596
Released 2024-Sep-30
9697

opentelemetry-otlp/src/exporter/http/mod.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -449,13 +449,13 @@ impl<B: HasHttpConfig> WithHttpConfig for B {
449449

450450
fn with_headers(mut self, headers: HashMap<String, String>) -> Self {
451451
// headers will be wrapped, so we must do some logic to unwrap first.
452-
self.http_client_config()
452+
let http_client_headers = self
453+
.http_client_config()
453454
.headers
454-
.iter_mut()
455-
.zip(headers)
456-
.for_each(|(http_client_headers, (key, value))| {
457-
http_client_headers.insert(key, super::url_decode(&value).unwrap_or(value));
458-
});
455+
.get_or_insert(HashMap::new());
456+
headers.into_iter().for_each(|(key, value)| {
457+
http_client_headers.insert(key, super::url_decode(&value).unwrap_or(value));
458+
});
459459
self
460460
}
461461
}
@@ -671,11 +671,14 @@ mod tests {
671671
}
672672

673673
#[test]
674-
fn test_http_exporter_builder_with_header() {
674+
fn test_http_exporter_builder_with_headers() {
675675
use std::collections::HashMap;
676676
// Arrange
677677
let initial_headers = HashMap::from([("k1".to_string(), "v1".to_string())]);
678-
let extra_headers = HashMap::from([("k2".to_string(), "v2".to_string())]);
678+
let extra_headers = HashMap::from([
679+
("k2".to_string(), "v2".to_string()),
680+
("k3".to_string(), "v3".to_string()),
681+
]);
679682
let expected_headers = initial_headers.iter().chain(extra_headers.iter()).fold(
680683
HashMap::new(),
681684
|mut acc, (k, v)| {

opentelemetry-sdk/CHANGELOG.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,24 @@
3333
}
3434
}
3535
```
36+
3637
- **Breaking** The SpanExporter::export() method no longer requires a mutable reference to self.
37-
Before:
38+
Before:
3839
```rust
39-
async fn export(&mut self, batch: Vec<SpanData>) -> OTelSdkResult
40+
async fn export(&mut self, batch: Vec<SpanData>) -> OTelSdkResult
4041
```
41-
After:
42-
```rust
43-
async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult
42+
After:
43+
```rust
44+
async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult
4445
```
46+
4547
Custom exporters will need to internally synchronize any mutable state, if applicable.
46-
48+
49+
- Bug Fix: `BatchLogProcessor` now correctly calls `shutdown` on the exporter
50+
when its `shutdown` is invoked.
51+
52+
- Reduced some info level logs to debug
53+
4754
## 0.28.0
4855

4956
Released 2025-Feb-10
@@ -85,7 +92,7 @@ field as metadata, a feature introduced in version 0.1.40.
8592
- `Resource::{new,empty,from_detectors,new_with_defaults,from_schema_url,merge,default}`.
8693
To create Resources you should only use `Resource::builder()` or `Resource::builder_empty()`. See
8794
[#2322](https://github.com/open-telemetry/opentelemetry-rust/pull/2322) for a migration guide.
88-
95+
8996
Example Usage:
9097

9198
```rust
@@ -173,7 +180,7 @@ field as metadata, a feature introduced in version 0.1.40.
173180
- Does not support `hyper`, `reqwest` HTTP Clients
174181
- Does not support multiple concurrent exports (`with_max_concurrent_exports`
175182
is not supported). This existed only for traces.
176-
183+
177184
If this applies to you, you can get the old behavior back by following steps
178185
below:
179186
- Enable one or more of the feature flag from below
@@ -241,7 +248,7 @@ limit.
241248
- *Breaking*: Rename namespaces for InMemoryExporters. (The module is still
242249
under "testing" feature flag)
243250
before:
244-
251+
245252
```rust
246253
opentelemetry_sdk::testing::logs::{InMemoryLogExporter,
247254
InMemoryLogExporterBuilder};
@@ -252,7 +259,7 @@ limit.
252259
```
253260

254261
now:
255-
262+
256263
```rust
257264
opentelemetry_sdk::logs::{InMemoryLogExporter, InMemoryLogExporterBuilder};
258265
opentelemetry_sdk::trace::{InMemorySpanExporter,

opentelemetry-sdk/src/logs/batch_log_processor.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{
2323
};
2424
use std::sync::mpsc::{self, RecvTimeoutError, SyncSender};
2525

26-
use opentelemetry::{otel_debug, otel_error, otel_info, otel_warn, InstrumentationScope};
26+
use opentelemetry::{otel_debug, otel_error, otel_warn, InstrumentationScope};
2727

2828
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
2929
use std::{cmp::min, env, sync::Mutex};
@@ -342,7 +342,7 @@ impl BatchLogProcessor {
342342
let handle = thread::Builder::new()
343343
.name("OpenTelemetry.Logs.BatchProcessor".to_string())
344344
.spawn(move || {
345-
otel_info!(
345+
otel_debug!(
346346
name: "BatchLogProcessor.ThreadStarted",
347347
interval_in_millisecs = config.scheduled_delay.as_millis(),
348348
max_export_batch_size = config.max_export_batch_size,
@@ -436,6 +436,7 @@ impl BatchLogProcessor {
436436
&current_batch_size,
437437
&config,
438438
);
439+
let _ = exporter.shutdown();
439440
let _ = sender.send(result);
440441

441442
otel_debug!(
@@ -475,7 +476,7 @@ impl BatchLogProcessor {
475476
}
476477
}
477478
}
478-
otel_info!(
479+
otel_debug!(
479480
name: "BatchLogProcessor.ThreadStopped"
480481
);
481482
})
@@ -925,7 +926,8 @@ mod tests {
925926
processor.shutdown().unwrap();
926927
// todo: expect to see errors here. How should we assert this?
927928
processor.emit(&mut record, &instrumentation);
928-
assert_eq!(1, exporter.get_emitted_logs().unwrap().len())
929+
assert_eq!(1, exporter.get_emitted_logs().unwrap().len());
930+
assert!(exporter.is_shutdown_called());
929931
}
930932

931933
#[tokio::test(flavor = "current_thread")]

opentelemetry-sdk/src/logs/in_memory_exporter.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::logs::{LogBatch, LogExporter};
44
use crate::Resource;
55
use opentelemetry::InstrumentationScope;
66
use std::borrow::Cow;
7+
use std::sync::atomic::AtomicBool;
78
use std::sync::{Arc, Mutex};
89

910
type LogResult<T> = Result<T, OTelSdkError>;
@@ -42,6 +43,7 @@ pub struct InMemoryLogExporter {
4243
logs: Arc<Mutex<Vec<OwnedLogData>>>,
4344
resource: Arc<Mutex<Resource>>,
4445
should_reset_on_shutdown: bool,
46+
shutdown_called: Arc<AtomicBool>,
4547
}
4648

4749
impl Default for InMemoryLogExporter {
@@ -124,6 +126,7 @@ impl InMemoryLogExporterBuilder {
124126
logs: Arc::new(Mutex::new(Vec::new())),
125127
resource: Arc::new(Mutex::new(Resource::builder().build())),
126128
should_reset_on_shutdown: self.reset_on_shutdown,
129+
shutdown_called: Arc::new(AtomicBool::new(false)),
127130
}
128131
}
129132

@@ -137,6 +140,12 @@ impl InMemoryLogExporterBuilder {
137140
}
138141

139142
impl InMemoryLogExporter {
143+
/// Returns true if shutdown was called.
144+
pub fn is_shutdown_called(&self) -> bool {
145+
self.shutdown_called
146+
.load(std::sync::atomic::Ordering::Relaxed)
147+
}
148+
140149
/// Returns the logs emitted via Logger as a vector of `LogDataWithResource`.
141150
///
142151
/// # Example
@@ -203,6 +212,8 @@ impl LogExporter for InMemoryLogExporter {
203212
}
204213

205214
fn shutdown(&mut self) -> OTelSdkResult {
215+
self.shutdown_called
216+
.store(true, std::sync::atomic::Ordering::Relaxed);
206217
if self.should_reset_on_shutdown {
207218
self.reset();
208219
}

opentelemetry-sdk/src/logs/simple_log_processor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ mod tests {
223223

224224
processor.emit(&mut record, &instrumentation);
225225

226-
assert_eq!(1, exporter.get_emitted_logs().unwrap().len())
226+
assert_eq!(1, exporter.get_emitted_logs().unwrap().len());
227+
assert!(exporter.is_shutdown_called());
227228
}
228229

229230
#[test]

opentelemetry-sdk/src/metrics/meter_provider.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl SdkMeterProvider {
110110
/// There is no guaranteed that all telemetry be flushed or all resources have
111111
/// been released on error.
112112
pub fn shutdown(&self) -> OTelSdkResult {
113-
otel_info!(
113+
otel_debug!(
114114
name: "MeterProvider.Shutdown",
115115
message = "User initiated shutdown of MeterProvider."
116116
);
@@ -164,7 +164,7 @@ impl Drop for SdkMeterProviderInner {
164164
reason = format!("{}", err)
165165
);
166166
} else {
167-
otel_info!(
167+
otel_debug!(
168168
name: "MeterProvider.Drop.ShutdownCompleted",
169169
);
170170
}
@@ -310,7 +310,7 @@ impl MeterProviderBuilder {
310310
}),
311311
};
312312

313-
otel_info!(
313+
otel_debug!(
314314
name: "MeterProvider.Built",
315315
);
316316
meter_provider
@@ -562,6 +562,25 @@ mod tests {
562562
assert_eq!(provider.inner.meters.lock().unwrap().len(), 5);
563563
}
564564

565+
#[test]
566+
fn same_meter_reused_same_scope_attributes() {
567+
let meter_provider = super::SdkMeterProvider::builder().build();
568+
let make_scope = |attributes| {
569+
InstrumentationScope::builder("test.meter")
570+
.with_version("v0.1.0")
571+
.with_schema_url("http://example.com")
572+
.with_attributes(attributes)
573+
.build()
574+
};
575+
576+
let _meter1 =
577+
meter_provider.meter_with_scope(make_scope(vec![KeyValue::new("key", "value1")]));
578+
let _meter2 =
579+
meter_provider.meter_with_scope(make_scope(vec![KeyValue::new("key", "value1")]));
580+
581+
assert_eq!(meter_provider.inner.meters.lock().unwrap().len(), 1);
582+
}
583+
565584
#[test]
566585
fn with_resource_multiple_calls_ensure_additive() {
567586
let builder = SdkMeterProvider::builder()

opentelemetry-sdk/src/metrics/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ mod tests {
782782
.build();
783783

784784
// Act
785-
// Meters are identical except for scope attributes, but scope attributes are not an identifying property.
785+
// Meters are identical.
786786
// Hence there should be a single metric stream output for this test.
787787
let make_scope = |attributes| {
788788
InstrumentationScope::builder("test.meter")
@@ -795,7 +795,7 @@ mod tests {
795795
let meter1 =
796796
meter_provider.meter_with_scope(make_scope(vec![KeyValue::new("key", "value1")]));
797797
let meter2 =
798-
meter_provider.meter_with_scope(make_scope(vec![KeyValue::new("key", "value2")]));
798+
meter_provider.meter_with_scope(make_scope(vec![KeyValue::new("key", "value1")]));
799799

800800
let counter1 = meter1
801801
.u64_counter("my_counter")

opentelemetry-sdk/src/metrics/periodic_reader.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl<E: PushMetricExporter> PeriodicReader<E> {
160160
.spawn(move || {
161161
let mut interval_start = Instant::now();
162162
let mut remaining_interval = interval;
163-
otel_info!(
163+
otel_debug!(
164164
name: "PeriodReaderThreadStarted",
165165
interval_in_millisecs = interval.as_millis(),
166166
);
@@ -190,16 +190,16 @@ impl<E: PushMetricExporter> PeriodicReader<E> {
190190

191191
if export_result.is_err() {
192192
if response_sender.send(false).is_err() {
193-
otel_info!(
193+
otel_debug!(
194194
name: "PeriodReader.Flush.ResponseSendError",
195-
message = "PeriodicReader's flush has failed, but unable to send this info back to caller.
195+
message = "PeriodicReader's flush has failed, but unable to send this info back to caller.
196196
This occurs when the caller has timed out waiting for the response. If you see this occuring frequently, consider increasing the flush timeout."
197197
);
198198
}
199199
} else if response_sender.send(true).is_err() {
200-
otel_info!(
200+
otel_debug!(
201201
name: "PeriodReader.Flush.ResponseSendError",
202-
message = "PeriodicReader's flush has completed successfully, but unable to send this info back to caller.
202+
message = "PeriodicReader's flush has completed successfully, but unable to send this info back to caller.
203203
This occurs when the caller has timed out waiting for the response. If you see this occuring frequently, consider increasing the flush timeout."
204204
);
205205
}
@@ -253,14 +253,14 @@ impl<E: PushMetricExporter> PeriodicReader<E> {
253253
if response_sender.send(false).is_err() {
254254
otel_info!(
255255
name: "PeriodReaderThreadShutdown.ResponseSendError",
256-
message = "PeriodicReader's shutdown has failed, but unable to send this info back to caller.
256+
message = "PeriodicReader's shutdown has failed, but unable to send this info back to caller.
257257
This occurs when the caller has timed out waiting for the response. If you see this occuring frequently, consider increasing the shutdown timeout."
258258
);
259259
}
260260
} else if response_sender.send(true).is_err() {
261-
otel_info!(
261+
otel_debug!(
262262
name: "PeriodReaderThreadShutdown.ResponseSendError",
263-
message = "PeriodicReader completed its shutdown, but unable to send this info back to caller.
263+
message = "PeriodicReader completed its shutdown, but unable to send this info back to caller.
264264
This occurs when the caller has timed out waiting for the response. If you see this occuring frequently, consider increasing the shutdown timeout."
265265
);
266266
}
@@ -312,7 +312,7 @@ impl<E: PushMetricExporter> PeriodicReader<E> {
312312
}
313313
}
314314
}
315-
otel_info!(
315+
otel_debug!(
316316
name: "PeriodReaderThreadStopped"
317317
);
318318
});
@@ -499,7 +499,7 @@ impl<E: PushMetricExporter> MetricReader for PeriodicReader<E> {
499499
/// This function SHOULD be obtained from the exporter.
500500
///
501501
/// If not configured, the Cumulative temporality SHOULD be used.
502-
///
502+
///
503503
/// [metric-reader]: https://github.com/open-telemetry/opentelemetry-specification/blob/0a78571045ca1dca48621c9648ec3c832c3c541c/specification/metrics/sdk.md#metricreader
504504
fn temporality(&self, kind: InstrumentKind) -> Temporality {
505505
kind.temporality_preference(self.inner.temporality(kind))

0 commit comments

Comments
 (0)