diff --git a/opentelemetry-appender-tracing/CHANGELOG.md b/opentelemetry-appender-tracing/CHANGELOG.md index ada890338..66d8d09cf 100644 --- a/opentelemetry-appender-tracing/CHANGELOG.md +++ b/opentelemetry-appender-tracing/CHANGELOG.md @@ -5,6 +5,32 @@ Fixes [1682](https://github.com/open-telemetry/opentelemetry-rust/issues/1682). "spec_unstable_logs_enabled" feature now do not suppress logs for other layers. +The special treatment of the "message" field has been extended when recording +string values. With this change, when a log is emitted with a field named +"message" (and string value), its value is directly assigned to the LogRecord’s +body rather than being stored as an attribute named "message". This offers a +slight performance improvement over previous. + +For example, the below will now produce LogRecord with the message value +populated as LogRecord's body: + +```rust +error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", message = "This is an example message"); +``` + +Previously, Body was only populated when the below style was used. + +```rust +error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", "This is an example message"); +``` + +This style, while slightly slower, should still be used when the value is not a +simple string, but require format arguments as in the below example. + +```rust +error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io", "This is an example message with format arguments {} and {}", "foo", "bar"); +``` + ## 0.28.1 Released 2025-Feb-12 diff --git a/opentelemetry-appender-tracing/src/layer.rs b/opentelemetry-appender-tracing/src/layer.rs index ebacc8938..ba5a58582 100644 --- a/opentelemetry-appender-tracing/src/layer.rs +++ b/opentelemetry-appender-tracing/src/layer.rs @@ -88,15 +88,14 @@ impl tracing::field::Visit for EventVisitor<'_, LR> { if is_duplicated_metadata(field.name()) { return; } - //TODO: Consider special casing "message" to populate body and document - // to users to use message field for log message, to avoid going to the - // record_debug, which has dyn dispatch, string allocation and - // formatting cost. - //TODO: Fix heap allocation. Check if lifetime of &str can be used // to optimize sync exporter scenario. - self.log_record - .add_attribute(Key::new(field.name()), AnyValue::from(value.to_owned())); + if field.name() == "message" { + self.log_record.set_body(AnyValue::from(value.to_owned())); + } else { + self.log_record + .add_attribute(Key::new(field.name()), AnyValue::from(value.to_owned())); + } } fn record_bool(&mut self, field: &tracing_core::Field, value: bool) {