tracing_actions_otlp/
proto_conversions.rs

1use std::time::SystemTime;
2
3use tracing_actions::{ActionEvent, AttributeValue, SpanStatus, TraceKind};
4
5use crate::{
6    proto::opentelemetry::{
7        common::v1::{any_value, AnyValue, KeyValue},
8        trace::v1::{
9            span::{self, Event},
10            status::StatusCode,
11            Span, Status,
12        },
13    },
14    OtlpAttributes,
15};
16
17impl From<OtlpAttributes> for Vec<KeyValue> {
18    fn from(value: OtlpAttributes) -> Self {
19        let mut attributes: Vec<KeyValue> = value
20            .other_attributes
21            .unwrap_or_default()
22            .into_iter()
23            .map(|(key, value)| KeyValue {
24                key,
25                value: Some(AnyValue {
26                    value: Some(any_value::Value::StringValue(value)),
27                }),
28            })
29            .collect();
30        attributes.push(KeyValue {
31            key: "service.name".to_string(),
32            value: Some(AnyValue {
33                value: Some(any_value::Value::StringValue(value.service_name)),
34            }),
35        });
36        attributes
37    }
38}
39
40impl From<&mut tracing_actions::ActionSpan> for Span {
41    fn from(value: &mut tracing_actions::ActionSpan) -> Self {
42        Self {
43            trace_id: value.trace_id.to_vec(),
44            span_id: value.span_id.to_vec(),
45            trace_state: value.trace_state.clone(),
46            parent_span_id: value
47                .parent_span_id
48                .map(|id| id.to_vec())
49                .unwrap_or_default(),
50            name: value
51                .metadata
52                .map(|m| m.name().to_string())
53                .unwrap_or_else(|| "unknown".to_string()),
54            kind: as_spankind(value.kind) as i32,
55            start_time_unix_nano: value
56                .start
57                .duration_since(SystemTime::UNIX_EPOCH)
58                .unwrap_or_default()
59                .as_nanos() as u64,
60            end_time_unix_nano: value
61                .end
62                .duration_since(SystemTime::UNIX_EPOCH)
63                .unwrap_or_default()
64                .as_nanos() as u64,
65            attributes: value.attributes.drain().map(KeyValue::from).collect(),
66            dropped_attributes_count: 0,
67            events: value.events.drain(..).map(Event::from).collect(),
68            dropped_events_count: 0,
69            links: vec![],
70            dropped_links_count: 0,
71            status: Some(value.status.into()),
72        }
73    }
74}
75
76fn as_spankind(value: TraceKind) -> span::SpanKind {
77    match value {
78        TraceKind::Client => span::SpanKind::Client,
79        TraceKind::Server => span::SpanKind::Server,
80    }
81}
82
83impl From<(&str, AttributeValue)> for KeyValue {
84    fn from(value: (&str, AttributeValue)) -> Self {
85        let (name, value) = value;
86        Self {
87            key: name.to_string(),
88            value: Some(AnyValue {
89                value: Some(match value {
90                    AttributeValue::String(s) => any_value::Value::StringValue(s),
91                    AttributeValue::F64(f) => any_value::Value::DoubleValue(f),
92                    AttributeValue::I64(i) => any_value::Value::IntValue(i),
93                    AttributeValue::U64(u) => any_value::Value::IntValue(u as i64),
94                    AttributeValue::I128(i) => any_value::Value::IntValue(i as i64),
95                    AttributeValue::U128(u) => any_value::Value::IntValue(u as i64),
96                    AttributeValue::Bool(b) => any_value::Value::BoolValue(b),
97                    AttributeValue::Error(e) => any_value::Value::StringValue(e),
98                }),
99            }),
100        }
101    }
102}
103
104impl From<ActionEvent> for Event {
105    fn from(mut value: ActionEvent) -> Self {
106        Self {
107            time_unix_nano: value
108                .timestamp
109                .duration_since(SystemTime::UNIX_EPOCH)
110                .unwrap_or_default()
111                .as_nanos() as u64,
112            name: value.metadata.name().to_string(),
113            attributes: value.attributes.drain().map(KeyValue::from).collect(),
114            dropped_attributes_count: 0,
115        }
116    }
117}
118
119impl From<SpanStatus> for Status {
120    fn from(value: SpanStatus) -> Self {
121        match value {
122            SpanStatus::Ok => Self {
123                message: "".to_string(),
124                code: StatusCode::Ok.into(),
125            },
126            SpanStatus::Error => Self {
127                message: "".to_string(),
128                code: StatusCode::Error.into(),
129            },
130        }
131    }
132}