1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use opentelemetry::api::core::KeyValue;
use opentelemetry::api::core::Value;
use opentelemetry::api::trace::{
self,
span_context::{SpanContext, SpanId, TraceId},
};
use opentelemetry::api::SpanKind;
use opentelemetry::exporter::trace::SpanData;
use opentelemetry::sdk::trace::evicted_hash_map::EvictedHashMap;
use opentelemetry::sdk::trace::evicted_queue::EvictedQueue;
use opentelemetry::sdk::Resource;
use std::fmt;
use std::sync::Arc;
use tracing::field::{Field, Visit};
use tracing_distributed::{Event, Span};
#[derive(Debug)]
#[doc(hidden)]
pub struct OpenTelemetryVisitor(pub(crate) EvictedHashMap);
impl Visit for OpenTelemetryVisitor {
fn record_i64(&mut self, field: &Field, value: i64) {
self.0
.insert(KeyValue::new(field.name(), Value::I64(value)))
}
fn record_u64(&mut self, field: &Field, value: u64) {
self.0
.insert(KeyValue::new(field.name(), Value::U64(value)))
}
fn record_bool(&mut self, field: &Field, value: bool) {
self.0
.insert(KeyValue::new(field.name(), Value::Bool(value)))
}
fn record_str(&mut self, field: &Field, value: &str) {
self.0.insert(KeyValue::new(field.name(), value))
}
fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
let s = format!("{:?}", value);
self.0.insert(KeyValue::new(field.name(), Value::String(s)))
}
}
pub(crate) fn event_to_values(
event: Event<OpenTelemetryVisitor, SpanId, TraceId>,
) -> trace::event::Event {
let mut attributes = event.values.0;
attributes.insert(KeyValue::new("event.level", event.meta.level().to_string()));
attributes.insert(KeyValue::new("event.target", event.meta.target()));
trace::event::Event {
name: event.meta.name().to_string(),
timestamp: event.initialized_at,
attributes: attributes
.into_iter()
.map(|(k, v)| KeyValue::new(k, v))
.collect(),
}
}
pub(crate) fn span_to_values(
span: Span<OpenTelemetryVisitor, SpanId, TraceId>,
events: EvictedQueue<trace::event::Event>,
) -> SpanData {
let mut attributes = span.values.0;
attributes.insert(KeyValue::new("span.level", span.meta.level().to_string()));
attributes.insert(KeyValue::new("span.service_name", span.service_name));
attributes.insert(KeyValue::new("span.target", span.meta.target()));
SpanData {
span_context: SpanContext::new(span.trace_id, span.id, 0, false),
parent_span_id: span.parent_id.unwrap_or_else(SpanId::invalid),
span_kind: SpanKind::Internal,
name: span.meta.name().to_string(),
start_time: span.initialized_at,
end_time: span.completed_at,
attributes,
message_events: events,
links: EvictedQueue::new(0),
status_code: opentelemetry::api::trace::span::StatusCode::OK,
status_message: "".to_string(),
resource: Arc::new(Resource::new(std::iter::empty())),
}
}