Skip to content

Commit 6b221e4

Browse files
authored
fix: Avoid stringifying int values unless necessary (#2795)
1 parent 66579ac commit 6b221e4

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

opentelemetry-appender-tracing/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ transparent to most users.
4242
implementations (SDK, processor, exporters) to leverage this additional
4343
information to determine if an event is enabled.
4444

45+
- `u64` and `usize` values are stored as `opentelemetry::logs::AnyValue::Int`
46+
when conversion is feasible. Otherwise stored as
47+
`opentelemetry::logs::AnyValue::String`. This avoids unnecessary string
48+
allocation when values can be represented in their original types.
49+
4550
## 0.28.1
4651

4752
Released 2025-Feb-12

opentelemetry-appender-tracing/src/layer.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,22 @@ impl<LR: LogRecord> tracing::field::Visit for EventVisitor<'_, LR> {
114114
.add_attribute(Key::new(field.name()), AnyValue::from(value));
115115
}
116116

117+
// TODO: We might need to do similar for record_i128,record_u128 too
118+
// to avoid stringification, unless needed.
119+
fn record_u64(&mut self, field: &tracing::field::Field, value: u64) {
120+
#[cfg(feature = "experimental_metadata_attributes")]
121+
if is_duplicated_metadata(field.name()) {
122+
return;
123+
}
124+
if let Ok(signed) = i64::try_from(value) {
125+
self.log_record
126+
.add_attribute(Key::new(field.name()), AnyValue::from(signed));
127+
} else {
128+
self.log_record
129+
.add_attribute(Key::new(field.name()), AnyValue::from(format!("{value:?}")));
130+
}
131+
}
132+
117133
// TODO: Remaining field types from AnyValue : Bytes, ListAny, Boolean
118134
}
119135

@@ -331,7 +347,11 @@ mod tests {
331347
let _guard = tracing::subscriber::set_default(subscriber);
332348

333349
// Act
334-
error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io");
350+
let small_u64value: u64 = 42;
351+
let big_u64value: u64 = u64::MAX;
352+
let small_usizevalue: usize = 42;
353+
let big_usizevalue: usize = usize::MAX;
354+
error!(name: "my-event-name", target: "my-system", event_id = 20, small_u64value, big_u64value, small_usizevalue, big_usizevalue, user_name = "otel", user_email = "otel@opentelemetry.io");
335355
assert!(logger_provider.force_flush().is_ok());
336356

337357
// Assert TODO: move to helper methods
@@ -362,9 +382,9 @@ mod tests {
362382

363383
// Validate attributes
364384
#[cfg(not(feature = "experimental_metadata_attributes"))]
365-
assert_eq!(log.record.attributes_iter().count(), 3);
366-
#[cfg(feature = "experimental_metadata_attributes")]
367385
assert_eq!(log.record.attributes_iter().count(), 7);
386+
#[cfg(feature = "experimental_metadata_attributes")]
387+
assert_eq!(log.record.attributes_iter().count(), 11);
368388
assert!(attributes_contains(
369389
&log.record,
370390
&Key::new("event_id"),
@@ -380,6 +400,26 @@ mod tests {
380400
&Key::new("user_email"),
381401
&AnyValue::String("otel@opentelemetry.io".into())
382402
));
403+
assert!(attributes_contains(
404+
&log.record,
405+
&Key::new("small_u64value"),
406+
&AnyValue::Int(42.into())
407+
));
408+
assert!(attributes_contains(
409+
&log.record,
410+
&Key::new("big_u64value"),
411+
&AnyValue::String(format!("{}", u64::MAX).into())
412+
));
413+
assert!(attributes_contains(
414+
&log.record,
415+
&Key::new("small_usizevalue"),
416+
&AnyValue::Int(42.into())
417+
));
418+
assert!(attributes_contains(
419+
&log.record,
420+
&Key::new("big_usizevalue"),
421+
&AnyValue::String(format!("{}", u64::MAX).into())
422+
));
383423
#[cfg(feature = "experimental_metadata_attributes")]
384424
{
385425
assert!(attributes_contains(
@@ -753,6 +793,10 @@ mod tests {
753793
TraceFlags::SAMPLED
754794
);
755795

796+
for attribute in log.record.attributes_iter() {
797+
println!("key: {:?}, value: {:?}", attribute.0, attribute.1);
798+
}
799+
756800
// Attributes can be polluted when we don't use this feature.
757801
#[cfg(feature = "experimental_metadata_attributes")]
758802
assert_eq!(log.record.attributes_iter().count(), 4);

0 commit comments

Comments
 (0)