1use std::{collections::BTreeMap, sync::Arc};
2
3use chrono::TimeZone;
4use ordered_float::NotNan;
5use uuid::Uuid;
6
7use super::{MetricTags, WithMetadata};
8use crate::{event, metrics::AgentDDSketch};
9
10#[allow(warnings, clippy::all, clippy::pedantic)]
11mod proto_event {
12 include!(concat!(env!("OUT_DIR"), "/event.rs"));
13}
14pub use event_wrapper::Event;
15pub use metric::Value as MetricValue;
16pub use proto_event::*;
17use vrl::value::{ObjectMap, Value as VrlValue};
18
19use super::EventFinalizers;
20use super::metadata::{Inner, default_schema_definition};
21use super::{EventMetadata, array, metric::MetricSketch};
22
23impl event_array::Events {
24 fn from_logs(logs: array::LogArray) -> Self {
27 let logs = logs.into_iter().map(Into::into).collect();
28 Self::Logs(LogArray { logs })
29 }
30
31 fn from_metrics(metrics: array::MetricArray) -> Self {
32 let metrics = metrics.into_iter().map(Into::into).collect();
33 Self::Metrics(MetricArray { metrics })
34 }
35
36 fn from_traces(traces: array::TraceArray) -> Self {
37 let traces = traces.into_iter().map(Into::into).collect();
38 Self::Traces(TraceArray { traces })
39 }
40}
41
42impl From<array::EventArray> for EventArray {
43 fn from(events: array::EventArray) -> Self {
44 let events = Some(match events {
45 array::EventArray::Logs(array) => event_array::Events::from_logs(array),
46 array::EventArray::Metrics(array) => event_array::Events::from_metrics(array),
47 array::EventArray::Traces(array) => event_array::Events::from_traces(array),
48 });
49 Self { events }
50 }
51}
52
53impl From<EventArray> for array::EventArray {
54 fn from(events: EventArray) -> Self {
55 let events = events.events.unwrap();
56
57 match events {
58 event_array::Events::Logs(logs) => {
59 array::EventArray::Logs(logs.logs.into_iter().map(Into::into).collect())
60 }
61 event_array::Events::Metrics(metrics) => {
62 array::EventArray::Metrics(metrics.metrics.into_iter().map(Into::into).collect())
63 }
64 event_array::Events::Traces(traces) => {
65 array::EventArray::Traces(traces.traces.into_iter().map(Into::into).collect())
66 }
67 }
68 }
69}
70
71impl From<Event> for EventWrapper {
72 fn from(event: Event) -> Self {
73 Self { event: Some(event) }
74 }
75}
76
77impl From<Log> for Event {
78 fn from(log: Log) -> Self {
79 Self::Log(log)
80 }
81}
82
83impl From<Metric> for Event {
84 fn from(metric: Metric) -> Self {
85 Self::Metric(metric)
86 }
87}
88
89impl From<Trace> for Event {
90 fn from(trace: Trace) -> Self {
91 Self::Trace(trace)
92 }
93}
94
95impl From<Log> for super::LogEvent {
96 fn from(log: Log) -> Self {
97 #[allow(deprecated)]
98 let metadata = log
99 .metadata_full
100 .map(Into::into)
101 .or_else(|| {
102 log.metadata
103 .and_then(decode_value)
104 .map(EventMetadata::default_with_value)
105 })
106 .unwrap_or_default();
107
108 if let Some(value) = log.value {
109 Self::from_parts(decode_value(value).unwrap_or(VrlValue::Null), metadata)
110 } else {
111 let fields = log
113 .fields
114 .into_iter()
115 .filter_map(|(k, v)| decode_value(v).map(|value| (k.into(), value)))
116 .collect::<ObjectMap>();
117
118 Self::from_map(fields, metadata)
119 }
120 }
121}
122
123impl From<Trace> for super::TraceEvent {
124 fn from(trace: Trace) -> Self {
125 #[allow(deprecated)]
126 let metadata = trace
127 .metadata_full
128 .map(Into::into)
129 .or_else(|| {
130 trace
131 .metadata
132 .and_then(decode_value)
133 .map(EventMetadata::default_with_value)
134 })
135 .unwrap_or_default();
136
137 let fields = trace
138 .fields
139 .into_iter()
140 .filter_map(|(k, v)| decode_value(v).map(|value| (k.into(), value)))
141 .collect::<ObjectMap>();
142
143 Self::from(super::LogEvent::from_map(fields, metadata))
144 }
145}
146
147impl From<MetricValue> for super::MetricValue {
148 fn from(value: MetricValue) -> Self {
149 match value {
150 MetricValue::Counter(counter) => Self::Counter {
151 value: counter.value,
152 },
153 MetricValue::Gauge(gauge) => Self::Gauge { value: gauge.value },
154 MetricValue::Set(set) => Self::Set {
155 values: set.values.into_iter().collect(),
156 },
157 MetricValue::Distribution1(dist) => Self::Distribution {
158 statistic: dist.statistic().into(),
159 samples: super::metric::zip_samples(dist.values, dist.sample_rates),
160 },
161 MetricValue::Distribution2(dist) => Self::Distribution {
162 statistic: dist.statistic().into(),
163 samples: dist.samples.into_iter().map(Into::into).collect(),
164 },
165 MetricValue::AggregatedHistogram1(hist) => Self::AggregatedHistogram {
166 buckets: super::metric::zip_buckets(
167 hist.buckets,
168 hist.counts.iter().map(|h| u64::from(*h)),
169 ),
170 count: u64::from(hist.count),
171 sum: hist.sum,
172 },
173 MetricValue::AggregatedHistogram2(hist) => Self::AggregatedHistogram {
174 buckets: hist.buckets.into_iter().map(Into::into).collect(),
175 count: u64::from(hist.count),
176 sum: hist.sum,
177 },
178 MetricValue::AggregatedHistogram3(hist) => Self::AggregatedHistogram {
179 buckets: hist.buckets.into_iter().map(Into::into).collect(),
180 count: hist.count,
181 sum: hist.sum,
182 },
183 MetricValue::AggregatedSummary1(summary) => Self::AggregatedSummary {
184 quantiles: super::metric::zip_quantiles(summary.quantiles, summary.values),
185 count: u64::from(summary.count),
186 sum: summary.sum,
187 },
188 MetricValue::AggregatedSummary2(summary) => Self::AggregatedSummary {
189 quantiles: summary.quantiles.into_iter().map(Into::into).collect(),
190 count: u64::from(summary.count),
191 sum: summary.sum,
192 },
193 MetricValue::AggregatedSummary3(summary) => Self::AggregatedSummary {
194 quantiles: summary.quantiles.into_iter().map(Into::into).collect(),
195 count: summary.count,
196 sum: summary.sum,
197 },
198 MetricValue::Sketch(sketch) => match sketch.sketch.unwrap() {
199 sketch::Sketch::AgentDdSketch(ddsketch) => Self::Sketch {
200 sketch: ddsketch.into(),
201 },
202 },
203 }
204 }
205}
206
207impl From<Metric> for super::Metric {
208 fn from(metric: Metric) -> Self {
209 let kind = match metric.kind() {
210 metric::Kind::Incremental => super::MetricKind::Incremental,
211 metric::Kind::Absolute => super::MetricKind::Absolute,
212 };
213
214 let name = metric.name;
215
216 let namespace = (!metric.namespace.is_empty()).then_some(metric.namespace);
217
218 #[allow(clippy::cast_sign_loss)]
220 let timestamp = metric.timestamp.map(|ts| {
221 chrono::Utc
222 .timestamp_opt(ts.seconds, ts.nanos as u32)
223 .single()
224 .expect("invalid timestamp")
225 });
226
227 let mut tags = MetricTags(
228 metric
229 .tags_v2
230 .into_iter()
231 .map(|(tag, values)| {
232 (
233 tag,
234 values
235 .values
236 .into_iter()
237 .map(|value| super::metric::TagValue::from(value.value))
238 .collect(),
239 )
240 })
241 .collect(),
242 );
243 tags.extend(metric.tags_v1);
247 let tags = (!tags.is_empty()).then_some(tags);
248
249 let value = super::MetricValue::from(metric.value.unwrap());
250
251 #[allow(deprecated)]
252 let metadata = metric
253 .metadata_full
254 .map(Into::into)
255 .or_else(|| {
256 metric
257 .metadata
258 .and_then(decode_value)
259 .map(EventMetadata::default_with_value)
260 })
261 .unwrap_or_default();
262
263 Self::new_with_metadata(name, kind, value, metadata)
264 .with_namespace(namespace)
265 .with_tags(tags)
266 .with_timestamp(timestamp)
267 .with_interval_ms(std::num::NonZeroU32::new(metric.interval_ms))
268 }
269}
270
271impl From<EventWrapper> for super::Event {
272 fn from(proto: EventWrapper) -> Self {
273 let event = proto.event.unwrap();
274
275 match event {
276 Event::Log(proto) => Self::Log(proto.into()),
277 Event::Metric(proto) => Self::Metric(proto.into()),
278 Event::Trace(proto) => Self::Trace(proto.into()),
279 }
280 }
281}
282
283impl From<super::LogEvent> for Log {
284 fn from(log_event: super::LogEvent) -> Self {
285 WithMetadata::<Self>::from(log_event).data
286 }
287}
288
289impl From<super::TraceEvent> for Trace {
290 fn from(trace: super::TraceEvent) -> Self {
291 WithMetadata::<Self>::from(trace).data
292 }
293}
294
295impl From<super::LogEvent> for WithMetadata<Log> {
296 fn from(log_event: super::LogEvent) -> Self {
297 let (value, metadata) = log_event.into_parts();
298
299 let (fields, value) = if let VrlValue::Object(fields) = value {
307 let fields = fields
309 .into_iter()
310 .map(|(k, v)| (k.into(), encode_value(v)))
311 .collect::<BTreeMap<_, _>>();
312
313 (fields, None)
314 } else {
315 let mut dummy_fields = BTreeMap::new();
319 dummy_fields.insert(".".to_owned(), encode_value(VrlValue::Null));
320
321 (dummy_fields, Some(encode_value(value)))
322 };
323
324 #[allow(deprecated)]
325 let data = Log {
326 fields,
327 value,
328 metadata: Some(encode_value(metadata.value().clone())),
329 metadata_full: Some(metadata.clone().into()),
330 };
331
332 Self { data, metadata }
333 }
334}
335
336impl From<super::TraceEvent> for WithMetadata<Trace> {
337 fn from(trace: super::TraceEvent) -> Self {
338 let (fields, metadata) = trace.into_parts();
339 let fields = fields
340 .into_iter()
341 .map(|(k, v)| (k.into(), encode_value(v)))
342 .collect::<BTreeMap<_, _>>();
343
344 #[allow(deprecated)]
345 let data = Trace {
346 fields,
347 metadata: Some(encode_value(metadata.value().clone())),
348 metadata_full: Some(metadata.clone().into()),
349 };
350
351 Self { data, metadata }
352 }
353}
354
355impl From<super::Metric> for Metric {
356 fn from(metric: super::Metric) -> Self {
357 WithMetadata::<Self>::from(metric).data
358 }
359}
360
361impl From<super::MetricValue> for MetricValue {
362 fn from(value: super::MetricValue) -> Self {
363 match value {
364 super::MetricValue::Counter { value } => Self::Counter(Counter { value }),
365 super::MetricValue::Gauge { value } => Self::Gauge(Gauge { value }),
366 super::MetricValue::Set { values } => Self::Set(Set {
367 values: values.into_iter().collect(),
368 }),
369 super::MetricValue::Distribution { samples, statistic } => {
370 Self::Distribution2(Distribution2 {
371 samples: samples.into_iter().map(Into::into).collect(),
372 statistic: match statistic {
373 super::StatisticKind::Histogram => StatisticKind::Histogram,
374 super::StatisticKind::Summary => StatisticKind::Summary,
375 }
376 .into(),
377 })
378 }
379 super::MetricValue::AggregatedHistogram {
380 buckets,
381 count,
382 sum,
383 } => Self::AggregatedHistogram3(AggregatedHistogram3 {
384 buckets: buckets.into_iter().map(Into::into).collect(),
385 count,
386 sum,
387 }),
388 super::MetricValue::AggregatedSummary {
389 quantiles,
390 count,
391 sum,
392 } => Self::AggregatedSummary3(AggregatedSummary3 {
393 quantiles: quantiles.into_iter().map(Into::into).collect(),
394 count,
395 sum,
396 }),
397 super::MetricValue::Sketch { sketch } => match sketch {
398 MetricSketch::AgentDDSketch(ddsketch) => {
399 let bin_map = ddsketch.bin_map();
400 let (keys, counts) = bin_map.into_parts();
401 let keys = keys.into_iter().map(i32::from).collect();
402 let counts = counts.into_iter().map(u32::from).collect();
403
404 Self::Sketch(Sketch {
405 sketch: Some(sketch::Sketch::AgentDdSketch(sketch::AgentDdSketch {
406 count: ddsketch.count(),
407 min: ddsketch.min().unwrap_or(f64::MAX),
408 max: ddsketch.max().unwrap_or(f64::MIN),
409 sum: ddsketch.sum().unwrap_or(0.0),
410 avg: ddsketch.avg().unwrap_or(0.0),
411 k: keys,
412 n: counts,
413 })),
414 })
415 }
416 },
417 }
418 }
419}
420
421impl From<super::Metric> for WithMetadata<Metric> {
422 fn from(metric: super::Metric) -> Self {
423 let (series, data, metadata) = metric.into_parts();
424 let name = series.name.name;
425 let namespace = series.name.namespace.unwrap_or_default();
426
427 #[allow(clippy::cast_possible_wrap)]
430 let timestamp = data.time.timestamp.map(|ts| prost_types::Timestamp {
431 seconds: ts.timestamp(),
432 nanos: ts.timestamp_subsec_nanos() as i32,
433 });
434
435 let interval_ms = data.time.interval_ms.map_or(0, std::num::NonZeroU32::get);
436
437 let tags = series.tags.unwrap_or_default();
438
439 let kind = match data.kind {
440 super::MetricKind::Incremental => metric::Kind::Incremental,
441 super::MetricKind::Absolute => metric::Kind::Absolute,
442 }
443 .into();
444
445 let metric = MetricValue::from(data.value);
446
447 let tags_v1 = tags
450 .0
451 .iter()
452 .filter_map(|(tag, values)| {
453 values
454 .as_single()
455 .map(|value| (tag.clone(), value.to_string()))
456 })
457 .collect();
458 let tags_v2 = tags
460 .0
461 .into_iter()
462 .map(|(tag, values)| {
463 let values = values
464 .into_iter()
465 .map(|value| TagValue {
466 value: value.into_option(),
467 })
468 .collect();
469 (tag, TagValues { values })
470 })
471 .collect();
472
473 #[allow(deprecated)]
474 let data = Metric {
475 name,
476 namespace,
477 timestamp,
478 tags_v1,
479 tags_v2,
480 kind,
481 interval_ms,
482 value: Some(metric),
483 metadata: Some(encode_value(metadata.value().clone())),
484 metadata_full: Some(metadata.clone().into()),
485 };
486
487 Self { data, metadata }
488 }
489}
490
491impl From<super::Event> for Event {
492 fn from(event: super::Event) -> Self {
493 WithMetadata::<Self>::from(event).data
494 }
495}
496
497impl From<super::Event> for WithMetadata<Event> {
498 fn from(event: super::Event) -> Self {
499 match event {
500 super::Event::Log(log_event) => WithMetadata::<Log>::from(log_event).into(),
501 super::Event::Metric(metric) => WithMetadata::<Metric>::from(metric).into(),
502 super::Event::Trace(trace) => WithMetadata::<Trace>::from(trace).into(),
503 }
504 }
505}
506
507impl From<super::Event> for EventWrapper {
508 fn from(event: super::Event) -> Self {
509 WithMetadata::<EventWrapper>::from(event).data
510 }
511}
512
513impl From<super::Event> for WithMetadata<EventWrapper> {
514 fn from(event: super::Event) -> Self {
515 WithMetadata::<Event>::from(event).into()
516 }
517}
518
519impl From<AgentDDSketch> for Sketch {
520 fn from(ddsketch: AgentDDSketch) -> Self {
521 let bin_map = ddsketch.bin_map();
522 let (keys, counts) = bin_map.into_parts();
523 let ddsketch = sketch::AgentDdSketch {
524 count: ddsketch.count(),
525 min: ddsketch.min().unwrap_or(f64::MAX),
526 max: ddsketch.max().unwrap_or(f64::MIN),
527 sum: ddsketch.sum().unwrap_or(0.0),
528 avg: ddsketch.avg().unwrap_or(0.0),
529 k: keys.into_iter().map(i32::from).collect(),
530 n: counts.into_iter().map(u32::from).collect(),
531 };
532 Sketch {
533 sketch: Some(sketch::Sketch::AgentDdSketch(ddsketch)),
534 }
535 }
536}
537
538impl From<sketch::AgentDdSketch> for MetricSketch {
539 fn from(sketch: sketch::AgentDdSketch) -> Self {
540 let keys = sketch
543 .k
544 .into_iter()
545 .map(|k| (k, k > 0))
546 .map(|(k, pos)| {
547 k.try_into()
548 .unwrap_or(if pos { i16::MAX } else { i16::MIN })
549 })
550 .collect::<Vec<_>>();
551 let counts = sketch
552 .n
553 .into_iter()
554 .map(|n| n.try_into().unwrap_or(u16::MAX))
555 .collect::<Vec<_>>();
556 MetricSketch::AgentDDSketch(
557 AgentDDSketch::from_raw(
558 sketch.count,
559 sketch.min,
560 sketch.max,
561 sketch.sum,
562 sketch.avg,
563 &keys,
564 &counts,
565 )
566 .expect("keys/counts were unexpectedly mismatched"),
567 )
568 }
569}
570
571impl From<super::metadata::Secrets> for Secrets {
572 fn from(value: super::metadata::Secrets) -> Self {
573 Self {
574 entries: value.into_iter().map(|(k, v)| (k, v.to_string())).collect(),
575 }
576 }
577}
578
579impl From<Secrets> for super::metadata::Secrets {
580 fn from(value: Secrets) -> Self {
581 let mut secrets = Self::new();
582 for (k, v) in value.entries {
583 secrets.insert(k, v);
584 }
585
586 secrets
587 }
588}
589
590impl From<super::DatadogMetricOriginMetadata> for DatadogOriginMetadata {
591 fn from(value: super::DatadogMetricOriginMetadata) -> Self {
592 Self {
593 origin_product: value.product(),
594 origin_category: value.category(),
595 origin_service: value.service(),
596 }
597 }
598}
599
600impl From<DatadogOriginMetadata> for super::DatadogMetricOriginMetadata {
601 fn from(value: DatadogOriginMetadata) -> Self {
602 Self::new(
603 value.origin_product,
604 value.origin_category,
605 value.origin_service,
606 )
607 }
608}
609
610impl From<crate::config::OutputId> for OutputId {
611 fn from(value: crate::config::OutputId) -> Self {
612 Self {
613 component: value.component.into_id(),
614 port: value.port,
615 }
616 }
617}
618
619impl From<OutputId> for crate::config::OutputId {
620 fn from(value: OutputId) -> Self {
621 Self::from((value.component, value.port))
622 }
623}
624
625impl From<EventMetadata> for Metadata {
626 fn from(value: EventMetadata) -> Self {
627 let super::metadata::Inner {
628 value,
629 secrets,
630 source_id,
631 source_type,
632 upstream_id,
633 datadog_origin_metadata,
634 source_event_id,
635 ..
636 } = value.into_owned();
637
638 let secrets = (!secrets.is_empty()).then(|| secrets.into());
639
640 Self {
641 value: Some(encode_value(value)),
642 datadog_origin_metadata: datadog_origin_metadata.map(Into::into),
643 source_id: source_id.map(|s| s.to_string()),
644 source_type: source_type.map(|s| s.to_string()),
645 upstream_id: upstream_id.map(|id| id.as_ref().clone()).map(Into::into),
646 secrets,
647 source_event_id: source_event_id.map_or(vec![], std::convert::Into::into),
648 }
649 }
650}
651
652impl From<Metadata> for EventMetadata {
653 fn from(value: Metadata) -> Self {
654 let Metadata {
655 value: metadata_value,
656 source_id,
657 source_type,
658 upstream_id,
659 secrets,
660 datadog_origin_metadata,
661 source_event_id,
662 } = value;
663
664 let metadata_value = metadata_value.and_then(decode_value);
665 let source_id = source_id.map(|s| Arc::new(s.into()));
666 let upstream_id = upstream_id.map(|id| Arc::new(id.into()));
667 let secrets = secrets.map(Into::into);
668 let datadog_origin_metadata = datadog_origin_metadata.map(Into::into);
669 let source_event_id = if source_event_id.is_empty() {
670 None
671 } else {
672 match Uuid::from_slice(&source_event_id) {
673 Ok(id) => Some(id),
674 Err(error) => {
675 error!(
676 %error,
677 source_event_id = %String::from_utf8_lossy(&source_event_id),
678 "Failed to parse source_event_id.",
679 );
680 None
681 }
682 }
683 };
684
685 EventMetadata {
686 inner: Arc::new(Inner {
687 value: metadata_value
688 .unwrap_or_else(|| vrl::value::Value::Object(ObjectMap::new())),
689 secrets: secrets.unwrap_or_default(),
690 finalizers: EventFinalizers::default(),
691 source_id,
692 source_type: source_type.map(Into::into),
693 upstream_id,
694 schema_definition: default_schema_definition(),
695 dropped_fields: ObjectMap::new(),
696 datadog_origin_metadata,
697 source_event_id,
698 }),
699 last_transform_timestamp: None,
700 }
701 }
702}
703
704fn decode_value(input: Value) -> Option<super::Value> {
705 match input.kind {
706 Some(value::Kind::RawBytes(data)) => Some(super::Value::Bytes(data)),
707 #[allow(clippy::cast_sign_loss)]
709 Some(value::Kind::Timestamp(ts)) => Some(super::Value::Timestamp(
710 chrono::Utc
711 .timestamp_opt(ts.seconds, ts.nanos as u32)
712 .single()
713 .expect("invalid timestamp"),
714 )),
715 Some(value::Kind::Integer(value)) => Some(super::Value::Integer(value)),
716 Some(value::Kind::Float(value)) => Some(super::Value::Float(NotNan::new(value).unwrap())),
717 Some(value::Kind::Boolean(value)) => Some(super::Value::Boolean(value)),
718 Some(value::Kind::Map(map)) => decode_map(map.fields),
719 Some(value::Kind::Array(array)) => decode_array(array.items),
720 Some(value::Kind::Null(_)) => Some(super::Value::Null),
721 None => {
722 error!("Encoded event contains unknown value kind.");
723 None
724 }
725 }
726}
727
728fn decode_map(fields: BTreeMap<String, Value>) -> Option<super::Value> {
729 fields
730 .into_iter()
731 .map(|(key, value)| decode_value(value).map(|value| (key.into(), value)))
732 .collect::<Option<ObjectMap>>()
733 .map(event::Value::Object)
734}
735
736fn decode_array(items: Vec<Value>) -> Option<super::Value> {
737 items
738 .into_iter()
739 .map(decode_value)
740 .collect::<Option<Vec<_>>>()
741 .map(super::Value::Array)
742}
743
744fn encode_value(value: super::Value) -> Value {
745 Value {
746 kind: match value {
747 super::Value::Bytes(b) => Some(value::Kind::RawBytes(b)),
748 super::Value::Regex(regex) => Some(value::Kind::RawBytes(regex.as_bytes())),
749 #[allow(clippy::cast_possible_wrap)]
752 super::Value::Timestamp(ts) => Some(value::Kind::Timestamp(prost_types::Timestamp {
753 seconds: ts.timestamp(),
754 nanos: ts.timestamp_subsec_nanos() as i32,
755 })),
756 super::Value::Integer(value) => Some(value::Kind::Integer(value)),
757 super::Value::Float(value) => Some(value::Kind::Float(value.into_inner())),
758 super::Value::Boolean(value) => Some(value::Kind::Boolean(value)),
759 super::Value::Object(fields) => Some(value::Kind::Map(encode_map(fields))),
760 super::Value::Array(items) => Some(value::Kind::Array(encode_array(items))),
761 super::Value::Null => Some(value::Kind::Null(ValueNull::NullValue as i32)),
762 },
763 }
764}
765
766fn encode_map(fields: ObjectMap) -> ValueMap {
767 ValueMap {
768 fields: fields
769 .into_iter()
770 .map(|(key, value)| (key.into(), encode_value(value)))
771 .collect(),
772 }
773}
774
775fn encode_array(items: Vec<super::Value>) -> ValueArray {
776 ValueArray {
777 items: items.into_iter().map(encode_value).collect(),
778 }
779}