Skip to content

Commit 426ad54

Browse files
committed
fix
1 parent 9add60e commit 426ad54

File tree

8 files changed

+38
-44
lines changed

8 files changed

+38
-44
lines changed

opentelemetry-appender-tracing/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ opentelemetry_sdk = { path = "../opentelemetry-sdk", features = ["logs", "testin
2626
tracing-log = "0.2"
2727
async-trait = { workspace = true }
2828
criterion = { workspace = true }
29+
smallvec = "1.13"
2930

3031
[target.'cfg(not(target_os = "windows"))'.dev-dependencies]
3132
pprof = { version = "0.13", features = ["flamegraph", "criterion"] }

opentelemetry-appender-tracing/benches/logs.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ fn benchmark_with_ot_layer(c: &mut Criterion, enabled: bool, bench_name: &str) {
139139
c.bench_function(bench_name, |b| {
140140
b.iter(|| {
141141
error!(
142-
name = "CheckoutFailed",
143-
book_id = "12345",
144-
book_title = "Rust Programming Adventures",
142+
// name = "CheckoutFailed",
143+
//book_id =12345,
144+
// book_title = "Rust Programming Adventures",
145145
"Unable to process checkout."
146146
);
147147
});

opentelemetry-appender-tracing/src/layer.rs

+14-23
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use opentelemetry::{
33
Key,
44
};
55
use std::borrow::Cow;
6-
use std::fmt::Write;
76
use tracing_core::{Level, Metadata};
87
#[cfg(feature = "experimental_metadata_attributes")]
98
use tracing_log::NormalizeEvent;
@@ -40,12 +39,9 @@ impl<'a, LR: LogRecord> EventVisitor<'a, LR> {
4039
fn new(log_record: &'a mut LR) -> Self {
4140
EventVisitor { log_record }
4241
}
43-
fn visit_metadata(&mut self, meta: &Metadata) {
44-
self.log_record
45-
.add_attribute(Key::new("name"), AnyValue::from(meta.name()));
46-
42+
fn visit_metadata(&mut self, _meta: &Metadata) {
4743
#[cfg(feature = "experimental_metadata_attributes")]
48-
self.visit_experimental_metadata(meta);
44+
self.visit_experimental_metadata(_meta);
4945
}
5046

5147
#[cfg(feature = "experimental_metadata_attributes")]
@@ -87,16 +83,10 @@ impl<'a, LR: LogRecord> tracing::field::Visit for EventVisitor<'a, LR> {
8783
return;
8884
}
8985
if field.name() == "message" {
90-
let mut body = String::new();
91-
write!(&mut body, "{:?}", value).unwrap();
92-
self.log_record.set_body(body.into());
86+
self.log_record.set_body(format!("{:?}", value).into());
9387
} else {
94-
let mut value_string = String::new();
95-
write!(&mut value_string, "{:?}", value).unwrap();
96-
self.log_record.add_attribute(
97-
Key::new(field.name()),
98-
AnyValue::from(format!("{value_string:?}")),
99-
);
88+
self.log_record
89+
.add_attribute(Key::new(field.name()), AnyValue::from(format!("{value:?}")));
10090
}
10191
}
10292

@@ -105,10 +95,8 @@ impl<'a, LR: LogRecord> tracing::field::Visit for EventVisitor<'a, LR> {
10595
if is_duplicated_metadata(field.name()) {
10696
return;
10797
}
108-
// Create a String with the exact capacity required
109-
let owned_string = String::from(value);
11098
self.log_record
111-
.add_attribute(Key::new(field.name()), AnyValue::from(owned_string));
99+
.add_attribute(Key::new(field.name()), AnyValue::from(value.to_owned()));
112100
}
113101

114102
fn record_bool(&mut self, field: &tracing_core::Field, value: bool) {
@@ -177,11 +165,11 @@ where
177165
#[cfg(not(feature = "experimental_metadata_attributes"))]
178166
let meta = event.metadata();
179167

180-
//let mut log_record: LogRecord = LogRecord::default();
181168
let mut log_record = self.logger.create_log_record();
182169
log_record.set_severity_number(severity_of_level(meta.level()));
183170
log_record.set_severity_text(meta.level().to_string().into());
184171
log_record.set_target(meta.target().to_string());
172+
log_record.set_event_name(meta.name());
185173

186174
let mut visitor = EventVisitor::new(&mut log_record);
187175
visitor.visit_metadata(meta);
@@ -224,9 +212,12 @@ mod tests {
224212
use opentelemetry_sdk::testing::logs::InMemoryLogsExporter;
225213
use opentelemetry_sdk::trace;
226214
use opentelemetry_sdk::trace::{Sampler, TracerProvider};
215+
use smallvec::SmallVec;
227216
use tracing::error;
228217
use tracing_subscriber::layer::SubscriberExt;
229218

219+
const PREALLOCATED_ATTRIBUTE_CAPACITY: usize = 8;
220+
230221
// cargo test --features=testing
231222
#[test]
232223
fn tracing_appender_standalone() {
@@ -264,7 +255,7 @@ mod tests {
264255
assert!(log.record.trace_context.is_none());
265256

266257
// Validate attributes
267-
let attributes: Vec<(Key, AnyValue)> = log
258+
let attributes: SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]> = log
268259
.record
269260
.attributes
270261
.clone()
@@ -361,7 +352,7 @@ mod tests {
361352
);
362353

363354
// validate attributes.
364-
let attributes: Vec<(Key, AnyValue)> = log
355+
let attributes: SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]> = log
365356
.record
366357
.attributes
367358
.clone()
@@ -428,7 +419,7 @@ mod tests {
428419
assert!(log.record.trace_context.is_none());
429420

430421
// Validate attributes
431-
let attributes: Vec<(Key, AnyValue)> = log
422+
let attributes: SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]> = log
432423
.record
433424
.attributes
434425
.clone()
@@ -525,7 +516,7 @@ mod tests {
525516
);
526517

527518
// validate attributes.
528-
let attributes: Vec<(Key, AnyValue)> = log
519+
let attributes: SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]> = log
529520
.record
530521
.attributes
531522
.clone()

opentelemetry-sdk/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ url = { workspace = true, optional = true }
2828
tokio = { workspace = true, features = ["rt", "time"], optional = true }
2929
tokio-stream = { workspace = true, optional = true }
3030
http = { workspace = true, optional = true }
31+
smallvec = "1.12"
3132

3233
[package.metadata.docs.rs]
3334
all-features = true

opentelemetry-sdk/src/logs/log_emitter.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ pub struct LoggerProvider {
4040

4141
/// Default logger name if empty string is provided.
4242
const DEFAULT_COMPONENT_NAME: &str = "rust.opentelemetry.io/sdk/logger";
43-
// According to a Go-specific study mentioned on https://go.dev/blog/slog,
44-
// up to 5 attributes is the most common case. We have chosen 8 as the default
45-
// capacity for attributes to avoid reallocation in common scenarios.
46-
const PREALLOCATED_ATTRIBUTE_CAPACITY: usize = 8;
4743

4844
impl opentelemetry::logs::LoggerProvider for LoggerProvider {
4945
type Logger = Logger;
@@ -251,10 +247,7 @@ impl opentelemetry::logs::Logger for Logger {
251247

252248
fn create_log_record(&self) -> Self::LogRecord {
253249
// Reserve attributes memory for perf optimization. This may change in future.
254-
LogRecord {
255-
attributes: Some(Vec::with_capacity(PREALLOCATED_ATTRIBUTE_CAPACITY)),
256-
..Default::default()
257-
}
250+
LogRecord::default()
258251
}
259252

260253
/// Emit a `LogRecord`.

opentelemetry-sdk/src/logs/log_processor.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ mod tests {
530530
use opentelemetry::logs::{Logger, LoggerProvider as _};
531531
use opentelemetry::Key;
532532
use opentelemetry::{logs::LogResult, KeyValue};
533+
use smallvec::smallvec;
533534
use std::borrow::Cow;
534535
use std::sync::{Arc, Mutex};
535536
use std::time::Duration;
@@ -816,7 +817,7 @@ mod tests {
816817
impl LogProcessor for FirstProcessor {
817818
fn emit(&self, data: &mut LogData) {
818819
// add attribute
819-
data.record.attributes.get_or_insert(vec![]).push((
820+
data.record.attributes.get_or_insert(smallvec![]).push((
820821
Key::from_static_str("processed_by"),
821822
AnyValue::String("FirstProcessor".into()),
822823
));

opentelemetry-sdk/src/logs/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ pub use record::{LogRecord, TraceContext};
1414
#[cfg(all(test, feature = "testing"))]
1515
mod tests {
1616
use super::*;
17+
use crate::logs::record::PREALLOCATED_ATTRIBUTE_CAPACITY;
1718
use crate::testing::logs::InMemoryLogsExporter;
1819
use crate::Resource;
1920
use opentelemetry::logs::LogRecord;
2021
use opentelemetry::logs::{Logger, LoggerProvider as _, Severity};
2122
use opentelemetry::{logs::AnyValue, Key, KeyValue};
23+
use smallvec::SmallVec;
2224
use std::borrow::Borrow;
2325
use std::collections::HashMap;
2426

@@ -80,7 +82,7 @@ mod tests {
8082
.expect("Atleast one log is expected to be present.");
8183
assert_eq!(log.instrumentation.name, "test-logger");
8284
assert_eq!(log.record.severity_number, Some(Severity::Error));
83-
let attributes: Vec<(Key, AnyValue)> = log
85+
let attributes: SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]> = log
8486
.record
8587
.attributes
8688
.clone()

opentelemetry-sdk/src/logs/record.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ use opentelemetry::{
33
trace::{SpanContext, SpanId, TraceFlags, TraceId},
44
Key,
55
};
6+
use smallvec::{smallvec, SmallVec};
67
use std::{borrow::Cow, time::SystemTime};
78

9+
// According to a Go-specific study mentioned on https://go.dev/blog/slog,
10+
// up to 5 attributes is the most common case. We have chosen 8 as the default
11+
// capacity for attributes to avoid reallocation in common scenarios.
12+
pub(crate) const PREALLOCATED_ATTRIBUTE_CAPACITY: usize = 8;
13+
814
#[derive(Debug, Default, Clone)]
915
#[non_exhaustive]
1016
/// LogRecord represents all data carried by a log record, and
@@ -34,7 +40,7 @@ pub struct LogRecord {
3440
pub body: Option<AnyValue>,
3541

3642
/// Additional attributes associated with this record
37-
pub attributes: Option<Vec<(Key, AnyValue)>>,
43+
pub attributes: Option<SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]>>,
3844
}
3945

4046
impl opentelemetry::logs::LogRecord for LogRecord {
@@ -91,8 +97,6 @@ impl opentelemetry::logs::LogRecord for LogRecord {
9197
{
9298
if let Some(ref mut attrs) = self.attributes {
9399
attrs.push((key.into(), value.into()));
94-
} else {
95-
self.attributes = Some(vec![(key.into(), value.into())]);
96100
}
97101
}
98102
}
@@ -186,16 +190,17 @@ mod tests {
186190
let mut log_record = LogRecord::default();
187191
let attributes = vec![(Key::new("key"), AnyValue::String("value".into()))];
188192
log_record.add_attributes(attributes.clone());
189-
assert_eq!(log_record.attributes, Some(attributes));
193+
let expected_attributes: SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]> =
194+
smallvec![(Key::new("key"), AnyValue::String("value".into()))];
195+
assert_eq!(log_record.attributes, Some(expected_attributes));
190196
}
191197

192198
#[test]
193199
fn test_set_attribute() {
194200
let mut log_record = LogRecord::default();
195201
log_record.add_attribute("key", "value");
196-
assert_eq!(
197-
log_record.attributes,
198-
Some(vec![(Key::new("key"), AnyValue::String("value".into()))])
199-
);
202+
let expected_attributes: SmallVec<[(Key, AnyValue); PREALLOCATED_ATTRIBUTE_CAPACITY]> =
203+
smallvec![(Key::new("key"), AnyValue::String("value".into()))];
204+
assert_eq!(log_record.attributes, Some(expected_attributes));
200205
}
201206
}

0 commit comments

Comments
 (0)