Skip to content

Commit cfc37e6

Browse files
committed
Implement additive with_resource for all signals
1 parent 1da56d4 commit cfc37e6

File tree

3 files changed

+88
-10
lines changed

3 files changed

+88
-10
lines changed

opentelemetry-sdk/src/logs/logger_provider.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,16 @@ impl LoggerProviderBuilder {
235235
}
236236

237237
/// The `Resource` to be associated with this Provider.
238+
///
239+
/// *Note*: Calls to this method are additive, each call merges the provided
240+
/// resource with the previous one.
238241
pub fn with_resource(self, resource: Resource) -> Self {
239-
LoggerProviderBuilder {
240-
resource: Some(resource),
241-
..self
242-
}
242+
let resource = match self.resource {
243+
Some(existing) => Some(existing.merge(&resource)),
244+
None => Some(resource),
245+
};
246+
247+
LoggerProviderBuilder { resource, ..self }
243248
}
244249

245250
/// Create a new provider from this configuration.
@@ -712,6 +717,35 @@ mod tests {
712717
assert_eq!(scoped_logger.instrumentation_scope().name(), "");
713718
}
714719

720+
#[test]
721+
fn with_resource_multiple_calls_ensure_additive() {
722+
let builder = SdkLoggerProvider::builder()
723+
.with_resource(Resource::new(vec![KeyValue::new("key1", "value1")]))
724+
.with_resource(Resource::new(vec![KeyValue::new("key2", "value2")]))
725+
.with_resource(
726+
Resource::builder_empty()
727+
.with_schema_url(vec![], "http://example.com")
728+
.build(),
729+
)
730+
.with_resource(Resource::new(vec![KeyValue::new("key3", "value3")]));
731+
732+
let resource = builder.resource.unwrap();
733+
734+
assert_eq!(
735+
resource.get(&Key::from_static_str("key1")),
736+
Some(Value::from("value1"))
737+
);
738+
assert_eq!(
739+
resource.get(&Key::from_static_str("key2")),
740+
Some(Value::from("value2"))
741+
);
742+
assert_eq!(
743+
resource.get(&Key::from_static_str("key3")),
744+
Some(Value::from("value3"))
745+
);
746+
assert_eq!(resource.schema_url(), Some("http://example.com"));
747+
}
748+
715749
#[derive(Debug)]
716750
pub(crate) struct LazyLogProcessor {
717751
shutdown_called: Arc<Mutex<bool>>,

opentelemetry-sdk/src/metrics/meter_provider.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ impl MeterProviderBuilder {
232232
/// with all [Meter]s the [MeterProvider] will create.
233233
///
234234
/// By default, if this option is not used, the default [Resource] will be used.
235-
/// Note that the calls to this method are additive, each call merges the provided
235+
///
236+
/// *Note*: Calls to this method are additive, each call merges the provided
236237
/// resource with the previous one.
237238
///
238239
/// [Meter]: opentelemetry::metrics::Meter

opentelemetry-sdk/src/trace/provider.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ impl opentelemetry::trace::TracerProvider for SdkTracerProvider {
293293
pub struct TracerProviderBuilder {
294294
processors: Vec<Box<dyn SpanProcessor>>,
295295
config: crate::trace::Config,
296+
resource: Option<Resource>,
296297
}
297298

298299
impl TracerProviderBuilder {
@@ -410,18 +411,28 @@ impl TracerProviderBuilder {
410411
///
411412
/// By default, if this option is not used, the default [Resource] will be used.
412413
///
414+
/// *Note*: Calls to this method are additive, each call merges the provided
415+
/// resource with the previous one.
416+
///
413417
/// [Tracer]: opentelemetry::trace::Tracer
414418
pub fn with_resource(self, resource: Resource) -> Self {
415-
TracerProviderBuilder {
416-
config: self.config.with_resource(resource),
417-
..self
418-
}
419+
let resource = match self.resource {
420+
Some(existing) => Some(existing.merge(&resource)),
421+
None => Some(resource),
422+
};
423+
424+
TracerProviderBuilder { resource, ..self }
419425
}
420426

421427
/// Create a new provider from this configuration.
422428
pub fn build(self) -> SdkTracerProvider {
423429
let mut config = self.config;
424430

431+
// Now, we can update the config with the resource.
432+
if let Some(resource) = self.resource {
433+
config = config.with_resource(resource);
434+
};
435+
425436
// Standard config will contain an owned [`Resource`] (either sdk default or use supplied)
426437
// we can optimize the common case with a static ref to avoid cloning the underlying
427438
// resource data for each span.
@@ -462,8 +473,8 @@ mod tests {
462473
SERVICE_NAME, TELEMETRY_SDK_LANGUAGE, TELEMETRY_SDK_NAME, TELEMETRY_SDK_VERSION,
463474
};
464475
use crate::trace::provider::TracerProviderInner;
465-
use crate::trace::SpanData;
466476
use crate::trace::{Config, Span, SpanProcessor};
477+
use crate::trace::{SdkTracerProvider, SpanData};
467478
use crate::Resource;
468479
use opentelemetry::trace::{Tracer, TracerProvider};
469480
use opentelemetry::{Context, Key, KeyValue, Value};
@@ -730,6 +741,38 @@ mod tests {
730741
assert!(test_tracer_1.provider().is_shutdown());
731742
}
732743

744+
#[test]
745+
fn with_resource_multiple_calls_ensure_additive() {
746+
let resource = SdkTracerProvider::builder()
747+
.with_resource(Resource::new(vec![KeyValue::new("key1", "value1")]))
748+
.with_resource(Resource::new(vec![KeyValue::new("key2", "value2")]))
749+
.with_resource(
750+
Resource::builder_empty()
751+
.with_schema_url(vec![], "http://example.com")
752+
.build(),
753+
)
754+
.with_resource(Resource::new(vec![KeyValue::new("key3", "value3")]))
755+
.build()
756+
.inner
757+
.config
758+
.resource
759+
.to_owned();
760+
761+
assert_eq!(
762+
resource.get(&Key::from_static_str("key1")),
763+
Some(Value::from("value1"))
764+
);
765+
assert_eq!(
766+
resource.get(&Key::from_static_str("key2")),
767+
Some(Value::from("value2"))
768+
);
769+
assert_eq!(
770+
resource.get(&Key::from_static_str("key3")),
771+
Some(Value::from("value3"))
772+
);
773+
assert_eq!(resource.schema_url(), Some("http://example.com"));
774+
}
775+
733776
#[derive(Debug)]
734777
struct CountingShutdownProcessor {
735778
shutdown_count: Arc<AtomicU32>,

0 commit comments

Comments
 (0)