Skip to content

Commit 345cd74

Browse files
authored
docs: improve with_resource() guidance to preserve SDK defaults (#3418)
1 parent f29a3d2 commit 345cd74

File tree

6 files changed

+138
-22
lines changed

6 files changed

+138
-22
lines changed

docs/metrics.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -730,10 +730,12 @@ Follow these guidelines when deciding where to attach metric attributes:
730730

731731
```rust
732732
// Example: Setting resource-level attributes
733-
let resource = Resource::new(vec![
734-
KeyValue::new("service.name", "payment-processor"),
735-
KeyValue::new("deployment.environment", "production"),
736-
]);
733+
// Use Resource::builder() to preserve SDK-provided defaults
734+
// (telemetry.sdk.*, service.name).
735+
let resource = Resource::builder()
736+
.with_service_name("payment-processor")
737+
.with_attributes([KeyValue::new("deployment.environment.name", "production")])
738+
.build();
737739
```
738740

739741
* **Meter-level attributes**: If the dimension applies only to a subset of

opentelemetry-sdk/src/logs/log_processor_with_async_runtime.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -775,13 +775,17 @@ mod tests {
775775
BatchLogProcessor::new(exporter.clone(), BatchConfig::default(), runtime::Tokio);
776776
let provider = SdkLoggerProvider::builder()
777777
.with_log_processor(processor)
778-
.with_resource(Resource::new(vec![
779-
KeyValue::new("k1", "v1"),
780-
KeyValue::new("k2", "v3"),
781-
KeyValue::new("k3", "v3"),
782-
KeyValue::new("k4", "v4"),
783-
KeyValue::new("k5", "v5"),
784-
]))
778+
.with_resource(
779+
Resource::builder_empty()
780+
.with_attributes(vec![
781+
KeyValue::new("k1", "v1"),
782+
KeyValue::new("k2", "v3"),
783+
KeyValue::new("k3", "v3"),
784+
KeyValue::new("k4", "v4"),
785+
KeyValue::new("k5", "v5"),
786+
])
787+
.build(),
788+
)
785789
.build();
786790
provider.force_flush().unwrap();
787791
assert_eq!(exporter.get_resource().unwrap().into_iter().count(), 5);

opentelemetry-sdk/src/logs/logger_provider.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,38 @@ impl LoggerProviderBuilder {
246246
LoggerProviderBuilder { processors, ..self }
247247
}
248248

249-
/// The `Resource` to be associated with this Provider.
249+
/// Associates a [Resource] with a [SdkLoggerProvider].
250+
///
251+
/// This [Resource] represents the entity producing telemetry and is associated
252+
/// with all `Logger`s the [SdkLoggerProvider] will create.
253+
///
254+
/// By default, if this option is not used, the default [Resource] will be used.
255+
///
256+
/// When constructing a [Resource], use [`Resource::builder()`] to preserve
257+
/// SDK-provided defaults such as `telemetry.sdk.*` and `service.name`.
258+
/// Using [`Resource::builder_empty()`] will **not** include these attributes.
259+
///
260+
/// # Example
261+
///
262+
/// ```
263+
/// use opentelemetry_sdk::{Resource, logs::SdkLoggerProvider};
264+
/// use opentelemetry::KeyValue;
265+
///
266+
/// let provider = SdkLoggerProvider::builder()
267+
/// .with_resource(
268+
/// Resource::builder()
269+
/// .with_service_name("my-service")
270+
/// .with_attributes([KeyValue::new("deployment.environment.name", "production")])
271+
/// .build(),
272+
/// )
273+
/// .build();
274+
/// ```
250275
///
251276
/// *Note*: Calls to this method are additive, each call merges the provided
252277
/// resource with the previous one.
278+
///
279+
/// [`Resource::builder()`]: Resource::builder
280+
/// [`Resource::builder_empty()`]: Resource::builder_empty
253281
pub fn with_resource(self, resource: Resource) -> Self {
254282
let resource = match self.resource {
255283
Some(existing) => Some(existing.merge(&resource)),
@@ -876,14 +904,26 @@ mod tests {
876904
#[test]
877905
fn with_resource_multiple_calls_ensure_additive() {
878906
let builder = SdkLoggerProvider::builder()
879-
.with_resource(Resource::new(vec![KeyValue::new("key1", "value1")]))
880-
.with_resource(Resource::new(vec![KeyValue::new("key2", "value2")]))
907+
.with_resource(
908+
Resource::builder_empty()
909+
.with_attributes(vec![KeyValue::new("key1", "value1")])
910+
.build(),
911+
)
912+
.with_resource(
913+
Resource::builder_empty()
914+
.with_attributes(vec![KeyValue::new("key2", "value2")])
915+
.build(),
916+
)
881917
.with_resource(
882918
Resource::builder_empty()
883919
.with_schema_url(vec![], "http://example.com")
884920
.build(),
885921
)
886-
.with_resource(Resource::new(vec![KeyValue::new("key3", "value3")]));
922+
.with_resource(
923+
Resource::builder_empty()
924+
.with_attributes(vec![KeyValue::new("key3", "value3")])
925+
.build(),
926+
);
887927

888928
let resource = builder.resource.unwrap();
889929

opentelemetry-sdk/src/metrics/meter_provider.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,32 @@ impl MeterProviderBuilder {
243243
///
244244
/// By default, if this option is not used, the default [Resource] will be used.
245245
///
246+
/// When constructing a [Resource], use [`Resource::builder()`] to preserve
247+
/// SDK-provided defaults such as `telemetry.sdk.*` and `service.name`.
248+
/// Using [`Resource::builder_empty()`] will **not** include these attributes.
249+
///
250+
/// # Example
251+
///
252+
/// ```
253+
/// use opentelemetry_sdk::{Resource, metrics::SdkMeterProvider};
254+
/// use opentelemetry::KeyValue;
255+
///
256+
/// let provider = SdkMeterProvider::builder()
257+
/// .with_resource(
258+
/// Resource::builder()
259+
/// .with_service_name("my-service")
260+
/// .with_attributes([KeyValue::new("deployment.environment.name", "production")])
261+
/// .build(),
262+
/// )
263+
/// .build();
264+
/// ```
265+
///
246266
/// *Note*: Calls to this method are additive, each call merges the provided
247267
/// resource with the previous one.
248268
///
249269
/// [Meter]: opentelemetry::metrics::Meter
270+
/// [`Resource::builder()`]: Resource::builder
271+
/// [`Resource::builder_empty()`]: Resource::builder_empty
250272
pub fn with_resource(mut self, resource: Resource) -> Self {
251273
self.resource = match self.resource {
252274
Some(existing) => Some(existing.merge(&resource)),
@@ -719,14 +741,26 @@ mod tests {
719741
#[test]
720742
fn with_resource_multiple_calls_ensure_additive() {
721743
let builder = SdkMeterProvider::builder()
722-
.with_resource(Resource::new(vec![KeyValue::new("key1", "value1")]))
723-
.with_resource(Resource::new(vec![KeyValue::new("key2", "value2")]))
744+
.with_resource(
745+
Resource::builder_empty()
746+
.with_attributes(vec![KeyValue::new("key1", "value1")])
747+
.build(),
748+
)
749+
.with_resource(
750+
Resource::builder_empty()
751+
.with_attributes(vec![KeyValue::new("key2", "value2")])
752+
.build(),
753+
)
724754
.with_resource(
725755
Resource::builder_empty()
726756
.with_schema_url(vec![], "http://example.com")
727757
.build(),
728758
)
729-
.with_resource(Resource::new(vec![KeyValue::new("key3", "value3")]));
759+
.with_resource(
760+
Resource::builder_empty()
761+
.with_attributes(vec![KeyValue::new("key3", "value3")])
762+
.build(),
763+
);
730764

731765
let resource = builder.resource.unwrap();
732766

opentelemetry-sdk/src/trace/provider.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,32 @@ impl TracerProviderBuilder {
426426
///
427427
/// By default, if this option is not used, the default [Resource] will be used.
428428
///
429+
/// When constructing a [Resource], use [`Resource::builder()`] to preserve
430+
/// SDK-provided defaults such as `telemetry.sdk.*` and `service.name`.
431+
/// Using [`Resource::builder_empty()`] will **not** include these attributes.
432+
///
433+
/// # Example
434+
///
435+
/// ```
436+
/// use opentelemetry_sdk::{Resource, trace::SdkTracerProvider};
437+
/// use opentelemetry::KeyValue;
438+
///
439+
/// let provider = SdkTracerProvider::builder()
440+
/// .with_resource(
441+
/// Resource::builder()
442+
/// .with_service_name("my-service")
443+
/// .with_attributes([KeyValue::new("deployment.environment.name", "production")])
444+
/// .build(),
445+
/// )
446+
/// .build();
447+
/// ```
448+
///
429449
/// *Note*: Calls to this method are additive, each call merges the provided
430450
/// resource with the previous one.
431451
///
432452
/// [Tracer]: opentelemetry::trace::Tracer
453+
/// [`Resource::builder()`]: Resource::builder
454+
/// [`Resource::builder_empty()`]: Resource::builder_empty
433455
pub fn with_resource(self, resource: Resource) -> Self {
434456
let resource = match self.resource {
435457
Some(existing) => Some(existing.merge(&resource)),
@@ -778,14 +800,26 @@ mod tests {
778800
#[test]
779801
fn with_resource_multiple_calls_ensure_additive() {
780802
let resource = SdkTracerProvider::builder()
781-
.with_resource(Resource::new(vec![KeyValue::new("key1", "value1")]))
782-
.with_resource(Resource::new(vec![KeyValue::new("key2", "value2")]))
803+
.with_resource(
804+
Resource::builder_empty()
805+
.with_attributes(vec![KeyValue::new("key1", "value1")])
806+
.build(),
807+
)
808+
.with_resource(
809+
Resource::builder_empty()
810+
.with_attributes(vec![KeyValue::new("key2", "value2")])
811+
.build(),
812+
)
783813
.with_resource(
784814
Resource::builder_empty()
785815
.with_schema_url(vec![], "http://example.com")
786816
.build(),
787817
)
788-
.with_resource(Resource::new(vec![KeyValue::new("key3", "value3")]))
818+
.with_resource(
819+
Resource::builder_empty()
820+
.with_attributes(vec![KeyValue::new("key3", "value3")])
821+
.build(),
822+
)
789823
.build()
790824
.inner
791825
.config

opentelemetry-sdk/src/trace/span_processor.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,9 @@ mod tests {
14571457
let mut processor = BatchSpanProcessor::new(exporter, config);
14581458

14591459
// Set a resource for the processor
1460-
let resource = Resource::new(vec![KeyValue::new("service.name", "test_service")]);
1460+
let resource = Resource::builder_empty()
1461+
.with_attributes(vec![KeyValue::new("service.name", "test_service")])
1462+
.build();
14611463
processor.set_resource(&resource);
14621464

14631465
// Create a span and send it to the processor

0 commit comments

Comments
 (0)