Skip to content

Commit 6baf3cb

Browse files
committed
fix: Report error using OTel convention
1 parent a442d62 commit 6baf3cb

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

opentelemetry-appender-tracing/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ when conversion is feasible. Otherwise stored as
4848
allocation when values can be represented in their original types.
4949
- Byte arrays are stored as `opentelemetry::logs::AnyValue::Bytes` instead
5050
of string.
51+
- `Error` fields are reported using attribute named "exception.message". For
52+
example, the below will now report an attribute named "exception.message",
53+
instead of previously reporting the user provided attribute "error".
54+
`error!(....error = &OTelSdkError::AlreadyShutdown as &dyn std::error::Error...)`
5155
- perf - small perf improvement by avoiding string allocation of `target`
5256

5357
## 0.28.1

opentelemetry-appender-tracing/src/layer.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@ impl<LR: LogRecord> tracing::field::Visit for EventVisitor<'_, LR> {
8080
}
8181
}
8282

83+
fn record_error(
84+
&mut self,
85+
_field: &tracing_core::Field,
86+
value: &(dyn std::error::Error + 'static),
87+
) {
88+
self.log_record.add_attribute(
89+
Key::new("exception.message"),
90+
AnyValue::from(value.to_string()),
91+
);
92+
// No ability to get exception.stacktrace or exception.type from the error today.
93+
}
94+
8395
fn record_bytes(&mut self, field: &tracing_core::Field, value: &[u8]) {
8496
self.log_record
8597
.add_attribute(Key::new(field.name()), AnyValue::from(value));
@@ -247,7 +259,7 @@ mod tests {
247259
use opentelemetry::trace::{TraceContextExt, TraceFlags, Tracer};
248260
use opentelemetry::InstrumentationScope;
249261
use opentelemetry::{logs::AnyValue, Key};
250-
use opentelemetry_sdk::error::OTelSdkResult;
262+
use opentelemetry_sdk::error::{OTelSdkError, OTelSdkResult};
251263
use opentelemetry_sdk::logs::{InMemoryLogExporter, LogProcessor};
252264
use opentelemetry_sdk::logs::{LogBatch, LogExporter};
253265
use opentelemetry_sdk::logs::{SdkLogRecord, SdkLoggerProvider};
@@ -355,7 +367,7 @@ mod tests {
355367
let big_u64value: u64 = u64::MAX;
356368
let small_usizevalue: usize = 42;
357369
let big_usizevalue: usize = usize::MAX;
358-
error!(name: "my-event-name", target: "my-system", event_id = 20, bytes = &b"abc"[..], small_u64value, big_u64value, small_usizevalue, big_usizevalue, user_name = "otel", user_email = "[email protected]");
370+
error!(name: "my-event-name", target: "my-system", event_id = 20, bytes = &b"abc"[..], error = &OTelSdkError::AlreadyShutdown as &dyn std::error::Error, small_u64value, big_u64value, small_usizevalue, big_usizevalue, user_name = "otel", user_email = "[email protected]");
359371
assert!(logger_provider.force_flush().is_ok());
360372

361373
// Assert TODO: move to helper methods
@@ -386,9 +398,9 @@ mod tests {
386398

387399
// Validate attributes
388400
#[cfg(not(feature = "experimental_metadata_attributes"))]
389-
assert_eq!(log.record.attributes_iter().count(), 8);
401+
assert_eq!(log.record.attributes_iter().count(), 9);
390402
#[cfg(feature = "experimental_metadata_attributes")]
391-
assert_eq!(log.record.attributes_iter().count(), 12);
403+
assert_eq!(log.record.attributes_iter().count(), 13);
392404
assert!(attributes_contains(
393405
&log.record,
394406
&Key::new("event_id"),
@@ -404,6 +416,11 @@ mod tests {
404416
&Key::new("user_email"),
405417
&AnyValue::String("[email protected]".into())
406418
));
419+
assert!(attributes_contains(
420+
&log.record,
421+
&Key::new("exception.message"),
422+
&AnyValue::String(OTelSdkError::AlreadyShutdown.to_string().into())
423+
));
407424
assert!(attributes_contains(
408425
&log.record,
409426
&Key::new("small_u64value"),
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1+
/// This module provides integration/bridge between OpenTelemetry and the `tracing` crate.
2+
/// TODO: Fill details
3+
/// 1. How is this different from tracing-opentelemetry crate?
4+
/// 2. How to use this crate?
5+
/// 3. What are the stability guarantees? How are fields mapped?
6+
/// 4. What are the limitations?
7+
///
18
pub mod layer;

0 commit comments

Comments
 (0)