diff --git a/opentelemetry-sdk/src/logs/mod.rs b/opentelemetry-sdk/src/logs/mod.rs index 598b0865ce..0da96bb730 100644 --- a/opentelemetry-sdk/src/logs/mod.rs +++ b/opentelemetry-sdk/src/logs/mod.rs @@ -35,10 +35,11 @@ pub mod log_processor_with_async_runtime; mod tests { use super::*; use crate::Resource; + use opentelemetry::baggage::BaggageExt; use opentelemetry::logs::LogRecord; use opentelemetry::logs::{Logger, LoggerProvider, Severity}; - use opentelemetry::InstrumentationScope; use opentelemetry::{logs::AnyValue, Key, KeyValue}; + use opentelemetry::{Context, InstrumentationScope}; use std::borrow::Borrow; use std::collections::HashMap; @@ -150,4 +151,63 @@ mod tests { .attributes() .eq(&[KeyValue::new("test_k", "test_v")])); } + + #[derive(Debug)] + struct EnrichWithBaggageProcessor; + impl LogProcessor for EnrichWithBaggageProcessor { + fn emit(&self, data: &mut SdkLogRecord, _instrumentation: &InstrumentationScope) { + Context::map_current(|cx| { + for (kk, vv) in cx.baggage().iter() { + data.add_attribute(kk.clone(), vv.0.clone()); + } + }); + } + + fn force_flush(&self) -> crate::error::OTelSdkResult { + Ok(()) + } + + fn shutdown(&self) -> crate::error::OTelSdkResult { + Ok(()) + } + } + #[test] + fn log_and_baggage() { + // Arrange + let exporter: InMemoryLogExporter = InMemoryLogExporter::default(); + let logger_provider = SdkLoggerProvider::builder() + .with_log_processor(EnrichWithBaggageProcessor) + .with_log_processor(SimpleLogProcessor::new(exporter.clone())) + .build(); + + // Act + let logger = logger_provider.logger("test-logger"); + let context_with_baggage = + Context::current_with_baggage(vec![KeyValue::new("key-from-bag", "value-from-bag")]); + let _cx_guard = context_with_baggage.attach(); + let mut log_record = logger.create_log_record(); + log_record.add_attribute("key", "value"); + logger.emit(log_record); + + // Assert + let exported_logs = exporter + .get_emitted_logs() + .expect("Logs are expected to be exported."); + assert_eq!(exported_logs.len(), 1); + let log = exported_logs + .first() + .expect("Atleast one log is expected to be present."); + assert_eq!(log.instrumentation.name(), "test-logger"); + assert_eq!(log.record.attributes_len(), 2); + + // Assert that the log record contains the baggage attribute + // and the attribute added to the log record. + assert!(log + .record + .attributes_contains(&Key::new("key"), &AnyValue::String("value".into()))); + assert!(log.record.attributes_contains( + &Key::new("key-from-bag"), + &AnyValue::String("value-from-bag".into()) + )); + } } diff --git a/opentelemetry/src/baggage.rs b/opentelemetry/src/baggage.rs index 75d97a3f14..ace8ca32e1 100644 --- a/opentelemetry/src/baggage.rs +++ b/opentelemetry/src/baggage.rs @@ -13,6 +13,10 @@ //! Baggage can be sent between systems using a baggage propagator in //! accordance with the [W3C Baggage] specification. //! +//! Note: Baggage is not automatically added to any telemetry. Users have to +//! explicitly add baggage entries to telemetry items. +//! +//! //! [W3C Baggage]: https://w3c.github.io/baggage use crate::{Context, Key, KeyValue, StringValue}; use std::collections::hash_map::Entry; @@ -75,10 +79,10 @@ impl Baggage { /// ``` /// use opentelemetry::{baggage::Baggage, StringValue}; /// - /// let mut cc = Baggage::new(); - /// let _ = cc.insert("my-name", "my-value"); + /// let mut baggage = Baggage::new(); + /// let _ = baggage.insert("my-name", "my-value"); /// - /// assert_eq!(cc.get("my-name"), Some(&StringValue::from("my-value"))) + /// assert_eq!(baggage.get("my-name"), Some(&StringValue::from("my-value"))) /// ``` pub fn get>(&self, key: K) -> Option<&StringValue> { self.inner.get(key.as_ref()).map(|(value, _metadata)| value) @@ -90,11 +94,11 @@ impl Baggage { /// ``` /// use opentelemetry::{baggage::{Baggage, BaggageMetadata}, StringValue}; /// - /// let mut cc = Baggage::new(); - /// let _ = cc.insert("my-name", "my-value"); + /// let mut baggage = Baggage::new(); + /// let _ = baggage.insert("my-name", "my-value"); /// /// // By default, the metadata is empty - /// assert_eq!(cc.get_with_metadata("my-name"), Some(&(StringValue::from("my-value"), BaggageMetadata::from("")))) + /// assert_eq!(baggage.get_with_metadata("my-name"), Some(&(StringValue::from("my-value"), BaggageMetadata::from("")))) /// ``` pub fn get_with_metadata>( &self, @@ -113,10 +117,10 @@ impl Baggage { /// ``` /// use opentelemetry::{baggage::Baggage, StringValue}; /// - /// let mut cc = Baggage::new(); - /// let _ = cc.insert("my-name", "my-value"); + /// let mut baggage = Baggage::new(); + /// let _ = baggage.insert("my-name", "my-value"); /// - /// assert_eq!(cc.get("my-name"), Some(&StringValue::from("my-value"))) + /// assert_eq!(baggage.get("my-name"), Some(&StringValue::from("my-value"))) /// ``` pub fn insert(&mut self, key: K, value: V) -> Option where @@ -127,7 +131,7 @@ impl Baggage { .map(|pair| pair.0) } - /// Inserts a name/value pair into the baggage. + /// Inserts a name/value(+metadata) pair into the baggage. /// /// Same with `insert`, if the name was not present, [`None`] will be returned. /// If the name is present, the old value and metadata will be returned. @@ -139,10 +143,10 @@ impl Baggage { /// ``` /// use opentelemetry::{baggage::{Baggage, BaggageMetadata}, StringValue}; /// - /// let mut cc = Baggage::new(); - /// let _ = cc.insert_with_metadata("my-name", "my-value", "test"); + /// let mut baggage = Baggage::new(); + /// let _ = baggage.insert_with_metadata("my-name", "my-value", "test"); /// - /// assert_eq!(cc.get_with_metadata("my-name"), Some(&(StringValue::from("my-value"), BaggageMetadata::from("test")))) + /// assert_eq!(baggage.get_with_metadata("my-name"), Some(&(StringValue::from("my-value"), BaggageMetadata::from("test")))) /// ``` pub fn insert_with_metadata( &mut self,