From 9797bbe92fd527a26c999132bd27733933cbe9fe Mon Sep 17 00:00:00 2001 From: Julian Tescher Date: Sun, 10 Apr 2022 13:22:57 -0400 Subject: [PATCH] Add `set_attributes` method for `Span` This adds the convenience method `Span::set_attributes` to set multiple attributes at a time. Co-authored-by: Srikanth Chekuri --- opentelemetry-api/src/trace/context.rs | 15 +++++++++++++++ opentelemetry-api/src/trace/span.rs | 19 +++++++++++++++++++ opentelemetry-sdk/src/trace/span.rs | 12 ++++++++++++ 3 files changed, 46 insertions(+) diff --git a/opentelemetry-api/src/trace/context.rs b/opentelemetry-api/src/trace/context.rs index 7dc553a00e..920bac6334 100644 --- a/opentelemetry-api/src/trace/context.rs +++ b/opentelemetry-api/src/trace/context.rs @@ -129,6 +129,21 @@ impl SpanRef<'_> { self.with_inner_mut(move |inner| inner.set_attribute(attribute)) } + /// Set multiple attributes of this span. + /// + /// Setting an attribute with the same key as an existing attribute + /// generally overwrites the existing attribute's value. + /// + /// Note that the OpenTelemetry project documents certain "[standard + /// attributes]" that have prescribed semantic meanings and are available via + /// the [opentelemetry_semantic_conventions] crate. + /// + /// [standard attributes]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/trace/semantic_conventions/README.md + /// [opentelemetry_semantic_conventions]: https://docs.rs/opentelemetry-semantic-conventions + pub fn set_attributes(&mut self, attributes: impl IntoIterator) { + self.with_inner_mut(move |inner| inner.set_attributes(attributes)) + } + /// Sets the status of this `Span`. /// /// If used, this will override the default span status, which is [`Status::Unset`]. diff --git a/opentelemetry-api/src/trace/span.rs b/opentelemetry-api/src/trace/span.rs index 0028596022..1984e1c4c7 100644 --- a/opentelemetry-api/src/trace/span.rs +++ b/opentelemetry-api/src/trace/span.rs @@ -120,6 +120,25 @@ pub trait Span { /// [opentelemetry_semantic_conventions]: https://docs.rs/opentelemetry-semantic-conventions fn set_attribute(&mut self, attribute: KeyValue); + /// Set multiple attributes of this span. + /// + /// Setting an attribute with the same key as an existing attribute + /// generally overwrites the existing attribute's value. + /// + /// Note that the OpenTelemetry project documents certain "[standard + /// attributes]" that have prescribed semantic meanings and are available via + /// the [opentelemetry_semantic_conventions] crate. + /// + /// [standard attributes]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/trace/semantic_conventions/README.md + /// [opentelemetry_semantic_conventions]: https://docs.rs/opentelemetry-semantic-conventions + fn set_attributes(&mut self, attributes: impl IntoIterator) { + if self.is_recording() { + for attr in attributes.into_iter() { + self.set_attribute(attr); + } + } + } + /// Sets the status of this `Span`. /// /// If used, this will override the default span status, which is [`Status::Unset`]. diff --git a/opentelemetry-sdk/src/trace/span.rs b/opentelemetry-sdk/src/trace/span.rs index 1c008d2e88..f02657fe1a 100644 --- a/opentelemetry-sdk/src/trace/span.rs +++ b/opentelemetry-sdk/src/trace/span.rs @@ -372,6 +372,18 @@ mod tests { }); } + #[test] + fn set_attributes() { + let mut span = create_span(); + let attributes = [KeyValue::new("k1", "v1"), KeyValue::new("k2", "v2")]; + span.set_attributes(attributes.clone()); + span.with_data(|data| { + for kv in attributes { + assert_eq!(data.attributes.get(&kv.key), Some(&kv.value)) + } + }); + } + #[test] fn set_status() { {