diff --git a/opentelemetry-appender-log/CHANGELOG.md b/opentelemetry-appender-log/CHANGELOG.md index 223d9a5a6f..1c92c570cd 100644 --- a/opentelemetry-appender-log/CHANGELOG.md +++ b/opentelemetry-appender-log/CHANGELOG.md @@ -2,6 +2,8 @@ ## vNext +- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Utilize the `LogRecord::set_target()` method to pass the log target to the SDK. + ## v0.4.0 - Add log key-values as attributes [#1628](https://github.com/open-telemetry/opentelemetry-rust/pull/1628) diff --git a/opentelemetry-appender-log/src/lib.rs b/opentelemetry-appender-log/src/lib.rs index 2ac07b45aa..d4ac9e894d 100644 --- a/opentelemetry-appender-log/src/lib.rs +++ b/opentelemetry-appender-log/src/lib.rs @@ -131,6 +131,7 @@ where log_record.set_severity_text(record.level().as_str().into()); log_record.set_body(AnyValue::from(record.args().to_string())); log_record.add_attributes(log_attributes(record.key_values())); + log_record.set_target(record.metadata().target().to_string()); self.logger.emit(log_record); } diff --git a/opentelemetry-appender-tracing/CHANGELOG.md b/opentelemetry-appender-tracing/CHANGELOG.md index edf820c902..67d1f55dc7 100644 --- a/opentelemetry-appender-tracing/CHANGELOG.md +++ b/opentelemetry-appender-tracing/CHANGELOG.md @@ -2,6 +2,9 @@ ## vNext +- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Utilize the `LogRecord::set_target()` method to pass the tracing target to the SDK. + Exporters might use the target to override the instrumentation scope, which previously contained "opentelemetry-appender-tracing". + ## v0.4.0 - Removed unwanted dependency on opentelemetry-sdk. diff --git a/opentelemetry-appender-tracing/src/layer.rs b/opentelemetry-appender-tracing/src/layer.rs index 1666890c40..45eb85dc92 100644 --- a/opentelemetry-appender-tracing/src/layer.rs +++ b/opentelemetry-appender-tracing/src/layer.rs @@ -172,6 +172,7 @@ where let mut log_record = self.logger.create_log_record(); log_record.set_severity_number(severity_of_level(meta.level())); log_record.set_severity_text(meta.level().to_string().into()); + log_record.set_target(meta.target().to_string()); let mut visitor = EventVisitor::new(&mut log_record); visitor.visit_metadata(meta); diff --git a/opentelemetry-otlp/CHANGELOG.md b/opentelemetry-otlp/CHANGELOG.md index 476be0026b..fcb26673c7 100644 --- a/opentelemetry-otlp/CHANGELOG.md +++ b/opentelemetry-otlp/CHANGELOG.md @@ -18,6 +18,7 @@ now use `.with_resource(RESOURCE::default())` to configure Resource when using - Bump MSRV to 1.70 [#1840](https://github.com/open-telemetry/opentelemetry-rust/pull/1840) - Fixing the OTLP HTTP/JSON exporter. [#1882](https://github.com/open-telemetry/opentelemetry-rust/pull/1882) - The exporter was broken in the previous release. +- **Breaking** [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) The OTLP logs exporter now overrides the [InstrumentationScope::name](https://github.com/open-telemetry/opentelemetry-proto/blob/b3060d2104df364136d75a35779e6bd48bac449a/opentelemetry/proto/common/v1/common.proto#L73) field with the `target` from `LogRecord`, if target is populated. ## v0.16.0 diff --git a/opentelemetry-proto/src/transform/common.rs b/opentelemetry-proto/src/transform/common.rs index 8197d90574..ff42479288 100644 --- a/opentelemetry-proto/src/transform/common.rs +++ b/opentelemetry-proto/src/transform/common.rs @@ -42,28 +42,68 @@ pub mod tonic { #[cfg(any(feature = "trace", feature = "logs"))] use opentelemetry_sdk::Resource; - impl From for InstrumentationScope { - fn from(library: opentelemetry_sdk::InstrumentationLibrary) -> Self { - InstrumentationScope { - name: library.name.into_owned(), - version: library.version.map(Cow::into_owned).unwrap_or_default(), - attributes: Attributes::from(library.attributes).0, - ..Default::default() + impl + From<( + opentelemetry_sdk::InstrumentationLibrary, + Option>, + )> for InstrumentationScope + { + fn from( + data: ( + opentelemetry_sdk::InstrumentationLibrary, + Option>, + ), + ) -> Self { + let (library, target) = data; + if let Some(t) = target { + InstrumentationScope { + name: t.to_string(), + version: String::new(), + attributes: vec![], + ..Default::default() + } + } else { + InstrumentationScope { + name: library.name.into_owned(), + version: library.version.map(Cow::into_owned).unwrap_or_default(), + attributes: Attributes::from(library.attributes).0, + ..Default::default() + } } } } - impl From<&opentelemetry_sdk::InstrumentationLibrary> for InstrumentationScope { - fn from(library: &opentelemetry_sdk::InstrumentationLibrary) -> Self { - InstrumentationScope { - name: library.name.to_string(), - version: library - .version - .as_ref() - .map(ToString::to_string) - .unwrap_or_default(), - attributes: Attributes::from(library.attributes.clone()).0, - ..Default::default() + impl + From<( + &opentelemetry_sdk::InstrumentationLibrary, + Option>, + )> for InstrumentationScope + { + fn from( + data: ( + &opentelemetry_sdk::InstrumentationLibrary, + Option>, + ), + ) -> Self { + let (library, target) = data; + if let Some(t) = target { + InstrumentationScope { + name: t.to_string(), + version: String::new(), + attributes: vec![], + ..Default::default() + } + } else { + InstrumentationScope { + name: library.name.to_string(), + version: library + .version + .as_ref() + .map(ToString::to_string) + .unwrap_or_default(), + attributes: Attributes::from(library.attributes.clone()).0, + ..Default::default() + } } } } diff --git a/opentelemetry-proto/src/transform/logs.rs b/opentelemetry-proto/src/transform/logs.rs index dbe3fa91e6..88d296e1d0 100644 --- a/opentelemetry-proto/src/transform/logs.rs +++ b/opentelemetry-proto/src/transform/logs.rs @@ -137,7 +137,7 @@ pub mod tonic { .clone() .map(Into::into) .unwrap_or_default(), - scope: Some(log_data.instrumentation.into()), + scope: Some((log_data.instrumentation, log_data.record.target.clone()).into()), log_records: vec![log_data.record.into()], }], } diff --git a/opentelemetry-proto/src/transform/metrics.rs b/opentelemetry-proto/src/transform/metrics.rs index f49fec06db..f718c96280 100644 --- a/opentelemetry-proto/src/transform/metrics.rs +++ b/opentelemetry-proto/src/transform/metrics.rs @@ -131,7 +131,7 @@ pub mod tonic { impl From<&SdkScopeMetrics> for TonicScopeMetrics { fn from(sm: &SdkScopeMetrics) -> Self { TonicScopeMetrics { - scope: Some((&sm.scope).into()), + scope: Some((&sm.scope, None).into()), metrics: sm.metrics.iter().map(Into::into).collect(), schema_url: sm .scope diff --git a/opentelemetry-proto/src/transform/trace.rs b/opentelemetry-proto/src/transform/trace.rs index 3f0003d44e..5c534301e3 100644 --- a/opentelemetry-proto/src/transform/trace.rs +++ b/opentelemetry-proto/src/transform/trace.rs @@ -61,7 +61,7 @@ pub mod tonic { .as_ref() .map(ToString::to_string) .unwrap_or_default(), - scope: Some(source_span.instrumentation_lib.into()), + scope: Some((source_span.instrumentation_lib, None).into()), spans: vec![Span { trace_id: source_span.span_context.trace_id().to_bytes().to_vec(), span_id: source_span.span_context.span_id().to_bytes().to_vec(), diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index ac35ff1695..61d99a629b 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -14,7 +14,7 @@ [`opentelemetry-aws`](https://crates.io/crates/opentelemetry-aws), version 0.10.0 or newer. - Performance Improvement - Counter/UpDownCounter instruments internally use - `RwLock` instead of `Mutex` to reduce contention. + `RwLock` instead of `Mutex` to reduce contention - **Breaking** [1726](https://github.com/open-telemetry/opentelemetry-rust/pull/1726) Update `LogProcessor::emit() method to take mutable reference to LogData. This is breaking @@ -47,6 +47,34 @@ - [1857](https://github.com/open-telemetry/opentelemetry-rust/pull/1857) Fixed an issue in Metrics SDK which prevented export errors from being send to global error handler. With the fix, errors occurring during export like OTLP Endpoint unresponsive shows up in stderr by default. +- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Added a `target` field to `LogRecord` structure, populated by `opentelemetry-appender-tracing` and `opentelemetry-appender-log` appenders. +```rust +async fn export<'a>(&mut self, batch: Vec>) -> LogResult<()>; +``` +where `LogRecord` within `LogData` now includes: +```rust +LogData { + LogRecord { + event_name, + target, // newly added + timestamp, + observed_timestamp, + trace_context, + trace_context, + severity_number, + body, + attributes + } + Instrumentation { + name, + version, + schema_url, + version + } +} +``` +The `LogRecord::target` field contains the actual target/component emitting the logs, while the `Instrumentation::name` contains the name of the OpenTelemetry appender. + ## v0.23.0 - Fix SimpleSpanProcessor to be consistent with log counterpart. Also removed diff --git a/opentelemetry-sdk/src/logs/record.rs b/opentelemetry-sdk/src/logs/record.rs index 5158fde713..3b79f10f7a 100644 --- a/opentelemetry-sdk/src/logs/record.rs +++ b/opentelemetry-sdk/src/logs/record.rs @@ -13,6 +13,9 @@ pub struct LogRecord { /// Event name. Optional as not all the logging API support it. pub event_name: Option>, + /// Target of the log record + pub target: Option>, + /// Record timestamp pub timestamp: Option, @@ -42,6 +45,14 @@ impl opentelemetry::logs::LogRecord for LogRecord { self.event_name = Some(name.into()); } + // Sets the `target` of a record + fn set_target(&mut self, _target: T) + where + T: Into>, + { + self.target = Some(_target.into()); + } + fn set_timestamp(&mut self, timestamp: SystemTime) { self.timestamp = Some(timestamp); } @@ -116,6 +127,20 @@ mod tests { use std::borrow::Cow; use std::time::SystemTime; + #[test] + fn test_set_eventname() { + let mut log_record = LogRecord::default(); + log_record.set_event_name("test_event"); + assert_eq!(log_record.event_name, Some(Cow::Borrowed("test_event"))); + } + + #[test] + fn test_set_target() { + let mut log_record = LogRecord::default(); + log_record.set_target("foo::bar"); + assert_eq!(log_record.target, Some(Cow::Borrowed("foo::bar"))); + } + #[test] fn test_set_timestamp() { let mut log_record = LogRecord::default(); diff --git a/opentelemetry/CHANGELOG.md b/opentelemetry/CHANGELOG.md index 1b578d9a2e..e932ec10cd 100644 --- a/opentelemetry/CHANGELOG.md +++ b/opentelemetry/CHANGELOG.md @@ -11,6 +11,9 @@ opaque string. Migration: Replace `.with_unit(Unit::new("myunit"))` with `.with_unit("myunit")`. +- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Introduced the `LogRecord::set_target()` method in the log bridge API. +This method allows appenders to set the target/component emitting the logs. + ## v0.23.0 ### Added diff --git a/opentelemetry/src/logs/noop.rs b/opentelemetry/src/logs/noop.rs index b2b9e8ebad..0264a76843 100644 --- a/opentelemetry/src/logs/noop.rs +++ b/opentelemetry/src/logs/noop.rs @@ -71,6 +71,14 @@ impl LogRecord for NoopLogRecord { V: Into, { } + + #[inline] + // Sets the `target` of a record + fn set_target(&mut self, _target: T) + where + T: Into>, + { + } } /// A no-op implementation of a [`Logger`] diff --git a/opentelemetry/src/logs/record.rs b/opentelemetry/src/logs/record.rs index 1dc80c937e..be00a7ab5c 100644 --- a/opentelemetry/src/logs/record.rs +++ b/opentelemetry/src/logs/record.rs @@ -10,6 +10,14 @@ pub trait LogRecord { { } + /// Sets the `target` of a record. + /// Currently, both `opentelemetry-appender-tracing` and `opentelemetry-appender-log` create a single logger + /// with a scope that doesn't accurately reflect the component emitting the logs. + /// Exporters MAY use this field to override the `instrumentation_scope.name`. + fn set_target(&mut self, _target: T) + where + T: Into>; + /// Sets the time when the event occurred measured by the origin clock, i.e. the time at the source. fn set_timestamp(&mut self, timestamp: SystemTime);