Skip to content

Commit b0bbed5

Browse files
committed
feat: add ResourceBuilder for creating Resources
1 parent 0428dd5 commit b0bbed5

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use opentelemetry::KeyValue;
2+
3+
use super::{Resource, ResourceDetector};
4+
5+
/// Builder to allow easy composition of a Resource
6+
#[derive(Debug, Default)]
7+
pub struct ResourceBuilder {
8+
resource: Resource,
9+
}
10+
11+
impl ResourceBuilder {
12+
/// Create ResourceBuilder with an empty [Resource].
13+
pub fn new_empty() -> Self {
14+
ResourceBuilder {
15+
resource: Resource::empty(),
16+
}
17+
}
18+
19+
/// Create ResourceBuilder with a default [Resource].
20+
pub fn new_default() -> Self {
21+
ResourceBuilder {
22+
resource: Resource::default(),
23+
}
24+
}
25+
26+
/// Add a single [ResourceDetector] to your resource.
27+
pub fn with_detector(self, detector: Box<dyn ResourceDetector>) -> Self {
28+
self.with_detectors(vec![detector])
29+
}
30+
31+
/// Add multiple [ResourceDetector] to your resource.
32+
pub fn with_detectors(mut self, detectors: Vec<Box<dyn ResourceDetector>>) -> Self {
33+
self.resource = self.resource.merge(&Resource::from_detectors(detectors));
34+
self
35+
}
36+
37+
/// Add a [KeyValue] to the resource.
38+
pub fn with_key_value(self, kv: KeyValue) -> Self {
39+
self.with_key_values(vec![kv])
40+
}
41+
42+
/// Add multiple [KeyValue]s to the resource.
43+
pub fn with_key_values<T: IntoIterator<Item = KeyValue>>(mut self, kvs: T) -> Self {
44+
self.resource = self.resource.merge(&Resource::new(kvs));
45+
self
46+
}
47+
48+
/// Create a [Resource] with the options provided to the [ResourceBuilder].
49+
pub fn build(self) -> Resource {
50+
self.resource
51+
}
52+
}
53+
54+
#[cfg(test)]
55+
mod tests {
56+
use opentelemetry::KeyValue;
57+
58+
use crate::resource::EnvResourceDetector;
59+
60+
use super::*;
61+
62+
#[test]
63+
fn detect_resource() {
64+
temp_env::with_vars(
65+
[
66+
(
67+
"OTEL_RESOURCE_ATTRIBUTES",
68+
Some("key=value, k = v , a= x, a=z"),
69+
),
70+
("IRRELEVANT", Some("20200810")),
71+
],
72+
|| {
73+
let resource = Resource::builder()
74+
.with_detector(Box::new(EnvResourceDetector::new()))
75+
.with_key_value(KeyValue::new("test1", "test_value"))
76+
.with_key_values(vec![
77+
KeyValue::new("test1", "test_value1"),
78+
KeyValue::new("test2", "test_value2"),
79+
])
80+
.build();
81+
82+
assert_eq!(
83+
resource,
84+
Resource::new(vec![
85+
KeyValue::new("key", "value"),
86+
KeyValue::new("test1", "test_value1"),
87+
KeyValue::new("test2", "test_value2"),
88+
KeyValue::new("k", "v"),
89+
KeyValue::new("a", "x"),
90+
KeyValue::new("a", "z"),
91+
])
92+
)
93+
},
94+
)
95+
}
96+
}

opentelemetry-sdk/src/resource/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
//!
2121
//! The OS and Process resource detectors are packaged separately in the
2222
//! [`opentelemetry-resource-detector` crate](https://github.com/open-telemetry/opentelemetry-rust-contrib/tree/main/opentelemetry-resource-detectors).
23+
mod builder;
2324
mod env;
2425
mod telemetry;
2526

@@ -36,6 +37,8 @@ use std::collections::{hash_map, HashMap};
3637
use std::ops::Deref;
3738
use std::sync::Arc;
3839

40+
use self::builder::ResourceBuilder;
41+
3942
/// Inner structure of `Resource` holding the actual data.
4043
/// This structure is designed to be shared among `Resource` instances via `Arc`.
4144
#[derive(Debug, Clone, PartialEq)]
@@ -62,6 +65,22 @@ impl Default for Resource {
6265
}
6366

6467
impl Resource {
68+
/// Creates a Builder that allows you to configure multiple aspects of the Resource.
69+
///
70+
/// If you want to start from a [Resource::default()] see [Resource::builder_default()].
71+
///
72+
/// Starts with a [Resource::empty()].
73+
pub fn builder() -> ResourceBuilder {
74+
ResourceBuilder::new_empty()
75+
}
76+
77+
/// Creates a Builder that allows you to configure multiple aspects of the Resource.
78+
///
79+
/// Starts with a [Resource::default()].
80+
pub fn builder_default() -> ResourceBuilder {
81+
ResourceBuilder::new_empty()
82+
}
83+
6584
/// Creates an empty resource.
6685
/// This is the basic constructor that initializes a resource with no attributes and no schema URL.
6786
pub fn empty() -> Self {

0 commit comments

Comments
 (0)