Skip to content

Commit 722893a

Browse files
committed
refactor: consolidate handling of otel type conversion from events
Handles extracting common values from LogEvent Value types: - `TraceId` - `SpanId` - `TraceState` - `TraceFlags` - Attribute fields (`Vec<KeyVal>`) Ref: LOG-19371
1 parent 86b98dc commit 722893a

File tree

3 files changed

+185
-195
lines changed

3 files changed

+185
-195
lines changed

src/sinks/opentelemetry/logs/model.rs

+13-45
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ use vector_lib::{
77

88
use opentelemetry::{
99
logs::{AnyValue as OtlpAnyValue, LogRecord, Severity},
10-
trace::{SpanContext, SpanId, TraceFlags, TraceId, TraceState},
10+
trace::{SpanContext, TraceState},
1111
};
1212
use opentelemetry_sdk::export::logs::LogData;
1313
use std::borrow::Cow;
1414

1515
use crate::sinks::opentelemetry::{
1616
models::{
1717
value_to_otlp_any_value, value_to_system_time, OpentelemetryModelMatch,
18-
OpentelemetryModelType, OpentelemetryResource, OpentelemetryScope,
18+
OpentelemetryModelType, OpentelemetryResource, OpentelemetryScope, OpentelemetrySpanId,
19+
OpentelemetryTraceFlags, OpentelemetryTraceId,
1920
},
2021
sink::OpentelemetrySinkError,
2122
};
@@ -106,49 +107,16 @@ impl TryFrom<Vec<Event>> for OpentelemetryLogsModel {
106107
let raw_span_id = metadata.get("span_id");
107108

108109
if raw_trace_id.or(raw_span_id).is_some() {
109-
let trace_id = if let Some(id) = raw_trace_id {
110-
match &id {
111-
Value::Bytes(bytes) => {
112-
let mut trace_id = [0; 16];
113-
match faster_hex::hex_decode(bytes, &mut trace_id) {
114-
Ok(_) => TraceId::from_bytes(trace_id),
115-
Err(_) => TraceId::INVALID,
116-
}
117-
}
118-
_ => TraceId::INVALID,
119-
}
120-
} else {
121-
TraceId::INVALID
122-
};
123-
124-
let span_id = if let Some(id) = raw_span_id {
125-
match &id {
126-
Value::Bytes(bytes) => {
127-
let mut span_id = [0; 8];
128-
match faster_hex::hex_decode(bytes, &mut span_id) {
129-
Ok(_) => SpanId::from_bytes(span_id),
130-
Err(_) => SpanId::INVALID,
131-
}
132-
}
133-
_ => SpanId::INVALID,
134-
}
135-
} else {
136-
SpanId::INVALID
137-
};
138-
139-
let trace_flags = if let Some(flags) = metadata.get("flags") {
140-
match flags {
141-
Value::Integer(flag) => TraceFlags::new(
142-
u8::try_from(*flag).unwrap_or(TraceFlags::NOT_SAMPLED.to_u8()),
143-
),
144-
_ => TraceFlags::NOT_SAMPLED,
145-
}
146-
} else {
147-
TraceFlags::NOT_SAMPLED
148-
};
149-
150-
let context =
151-
SpanContext::new(trace_id, span_id, trace_flags, false, TraceState::NONE);
110+
let trace_id: OpentelemetryTraceId = raw_trace_id.into();
111+
let span_id: OpentelemetrySpanId = raw_span_id.into();
112+
let trace_flags: OpentelemetryTraceFlags = metadata.get("flags").into();
113+
let context = SpanContext::new(
114+
trace_id.into(),
115+
span_id.into(),
116+
trace_flags.into(),
117+
false,
118+
TraceState::NONE,
119+
);
152120

153121
record_builder = record_builder.with_span_context(&context);
154122
}

src/sinks/opentelemetry/models.rs

+125-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use chrono::SecondsFormat;
2-
use std::ops::SubAssign;
2+
use std::{ops::SubAssign, str::FromStr};
33

44
use std::collections::HashMap;
55
use vector_lib::{
@@ -13,9 +13,11 @@ use super::{
1313
traces::model::OpentelemetryTracesModel,
1414
};
1515
use opentelemetry::{
16-
logs::AnyValue as OtlpAnyValue, Array as OtlpArray, InstrumentationLibrary, Key, KeyValue,
17-
StringValue, Value as OtlpValue,
16+
logs::AnyValue as OtlpAnyValue,
17+
trace::{SpanId, TraceFlags, TraceId, TraceState},
18+
Array as OtlpArray, InstrumentationLibrary, Key, KeyValue, StringValue, Value as OtlpValue,
1819
};
20+
1921
use opentelemetry_sdk::Resource;
2022
use std::{
2123
borrow::Cow,
@@ -119,10 +121,119 @@ pub fn value_to_system_time(value: &Value) -> SystemTime {
119121

120122
#[derive(Debug)]
121123
pub struct OpentelemetryResource {
122-
pub attributes: Vec<KeyValue>,
124+
pub attributes: OpentelemetryAttributes,
123125
pub schema_url: Cow<'static, str>,
124126
}
125127

128+
pub struct OpentelemetryTraceId(TraceId);
129+
130+
impl From<Option<&Value>> for OpentelemetryTraceId {
131+
fn from(bytes: Option<&Value>) -> Self {
132+
match bytes {
133+
Some(Value::Bytes(bytes)) => {
134+
let mut trace_id = [0; 16];
135+
match faster_hex::hex_decode(bytes, &mut trace_id) {
136+
Ok(_) => Self(TraceId::from_bytes(trace_id)),
137+
Err(_) => Self(TraceId::INVALID),
138+
}
139+
}
140+
_ => Self(TraceId::INVALID),
141+
}
142+
}
143+
}
144+
145+
impl From<OpentelemetryTraceId> for TraceId {
146+
fn from(trace_id: OpentelemetryTraceId) -> TraceId {
147+
trace_id.0
148+
}
149+
}
150+
151+
pub struct OpentelemetrySpanId(SpanId);
152+
153+
impl From<Option<&Value>> for OpentelemetrySpanId {
154+
fn from(bytes: Option<&Value>) -> Self {
155+
match bytes {
156+
Some(Value::Bytes(bytes)) => {
157+
let mut span_id = [0; 8];
158+
match faster_hex::hex_decode(bytes, &mut span_id) {
159+
Ok(_) => Self(SpanId::from_bytes(span_id)),
160+
Err(_) => Self(SpanId::INVALID),
161+
}
162+
}
163+
_ => Self(SpanId::INVALID),
164+
}
165+
}
166+
}
167+
168+
impl From<OpentelemetrySpanId> for SpanId {
169+
fn from(span_id: OpentelemetrySpanId) -> Self {
170+
span_id.0
171+
}
172+
}
173+
174+
pub struct OpentelemetryTraceState(TraceState);
175+
176+
impl From<Option<&Value>> for OpentelemetryTraceState {
177+
fn from(bytes: Option<&Value>) -> Self {
178+
match bytes {
179+
Some(Value::Bytes(bytes)) => {
180+
let str = String::from_utf8_lossy(bytes);
181+
Self(TraceState::from_str(&str).unwrap_or_default())
182+
}
183+
_ => Self(TraceState::NONE),
184+
}
185+
}
186+
}
187+
188+
impl From<OpentelemetryTraceState> for TraceState {
189+
fn from(state: OpentelemetryTraceState) -> Self {
190+
state.0
191+
}
192+
}
193+
194+
pub struct OpentelemetryTraceFlags(TraceFlags);
195+
196+
impl From<Option<&Value>> for OpentelemetryTraceFlags {
197+
fn from(bytes: Option<&Value>) -> Self {
198+
match bytes {
199+
Some(Value::Integer(flag)) => Self(TraceFlags::new(
200+
u8::try_from(*flag).unwrap_or(TraceFlags::NOT_SAMPLED.to_u8()),
201+
)),
202+
_ => Self(TraceFlags::NOT_SAMPLED),
203+
}
204+
}
205+
}
206+
207+
impl From<OpentelemetryTraceFlags> for TraceFlags {
208+
fn from(flags: OpentelemetryTraceFlags) -> Self {
209+
flags.0
210+
}
211+
}
212+
213+
#[derive(Default, Debug)]
214+
pub struct OpentelemetryAttributes(Vec<KeyValue>);
215+
216+
impl From<Option<&Value>> for OpentelemetryAttributes {
217+
fn from(value: Option<&Value>) -> Self {
218+
match value {
219+
Some(Value::Object(obj)) => Self(
220+
obj.iter()
221+
.map(|(key, value)| {
222+
KeyValue::new(key.to_string(), value_to_otlp_value(value.clone()))
223+
})
224+
.collect(),
225+
),
226+
_ => Self(vec![]),
227+
}
228+
}
229+
}
230+
231+
impl From<OpentelemetryAttributes> for Vec<KeyValue> {
232+
fn from(attrs: OpentelemetryAttributes) -> Self {
233+
attrs.0
234+
}
235+
}
236+
126237
impl From<&LogEvent> for OpentelemetryResource {
127238
fn from(log: &LogEvent) -> Self {
128239
let mut attributes = vec![];
@@ -143,15 +254,15 @@ impl From<&LogEvent> for OpentelemetryResource {
143254
}
144255

145256
OpentelemetryResource {
146-
attributes,
257+
attributes: OpentelemetryAttributes(attributes),
147258
schema_url,
148259
}
149260
}
150261
}
151262

152263
impl From<OpentelemetryResource> for Resource {
153264
fn from(val: OpentelemetryResource) -> Self {
154-
Resource::from_schema_url(val.attributes, val.schema_url)
265+
Resource::from_schema_url(Into::<Vec<KeyValue>>::into(val.attributes), val.schema_url)
155266
}
156267
}
157268

@@ -160,7 +271,7 @@ pub struct OpentelemetryScope {
160271
pub name: Cow<'static, str>,
161272
pub version: Option<Cow<'static, str>>,
162273
pub schema_url: Option<Cow<'static, str>>,
163-
pub attributes: Vec<KeyValue>,
274+
pub attributes: OpentelemetryAttributes,
164275
}
165276

166277
impl From<&LogEvent> for OpentelemetryScope {
@@ -205,14 +316,19 @@ impl From<&LogEvent> for OpentelemetryScope {
205316
name,
206317
version,
207318
schema_url,
208-
attributes,
319+
attributes: OpentelemetryAttributes(attributes),
209320
}
210321
}
211322
}
212323

213324
impl From<OpentelemetryScope> for InstrumentationLibrary {
214325
fn from(val: OpentelemetryScope) -> Self {
215-
InstrumentationLibrary::new(val.name, val.version, val.schema_url, Some(val.attributes))
326+
InstrumentationLibrary::new(
327+
val.name,
328+
val.version,
329+
val.schema_url,
330+
Some(val.attributes.into()),
331+
)
216332
}
217333
}
218334

0 commit comments

Comments
 (0)