micromegas_analytics/lakehouse/
block_object_decoder.rs1use crate::lakehouse::otel::block_decoders::{
7 OtelLogsBlockDecoder, OtelMetricsBlockDecoder, OtelTracesBlockDecoder,
8};
9use crate::lakehouse::parse_block_table_function::transit_value_to_jsonb;
10use crate::metadata::StreamMetadata;
11use crate::payload::parse_block;
12use anyhow::Result;
13use micromegas_ingestion::web_ingestion_service::{
14 FORMAT_OTLP_LOGS, FORMAT_OTLP_METRICS, FORMAT_OTLP_TRACES, FORMAT_TRANSIT,
15};
16use micromegas_telemetry::block_wire_format::BlockPayload;
17use micromegas_tracing::prelude::*;
18use micromegas_transit::value::Value as TransitValue;
19use std::collections::HashMap;
20use std::fmt::Debug;
21use std::sync::Arc;
22
23pub trait ObjectVisitor {
25 fn visit(&mut self, type_name: &str, value: &[u8]) -> Result<bool>;
27
28 fn skip(&mut self) -> Result<bool>;
32}
33
34pub trait BlockObjectDecoder: Send + Sync + Debug {
36 fn decode(
37 &self,
38 stream: &StreamMetadata,
39 payload: &BlockPayload,
40 visitor: &mut dyn ObjectVisitor,
41 ) -> Result<()>;
42}
43
44pub type BlockObjectDecoderMap = HashMap<&'static str, Arc<dyn BlockObjectDecoder>>;
47
48#[derive(Debug)]
52pub struct TransitBlockDecoder;
53
54impl BlockObjectDecoder for TransitBlockDecoder {
55 fn decode(
56 &self,
57 stream: &StreamMetadata,
58 payload: &BlockPayload,
59 visitor: &mut dyn ObjectVisitor,
60 ) -> Result<()> {
61 parse_block(stream, payload, |value| {
62 if let TransitValue::Object(obj) = value {
63 let jsonb_val = transit_value_to_jsonb(value);
64 let mut buf = Vec::new();
65 jsonb_val.write_to_vec(&mut buf);
66 visitor.visit(obj.type_name, &buf)
67 } else {
68 warn!("parse_block: skipping non-Object value in transit block");
72 visitor.skip()
73 }
74 })?;
75 Ok(())
76 }
77}
78
79pub fn default_block_object_decoders() -> Arc<BlockObjectDecoderMap> {
81 let mut m: BlockObjectDecoderMap = HashMap::new();
82 m.insert(
83 FORMAT_TRANSIT,
84 Arc::new(TransitBlockDecoder) as Arc<dyn BlockObjectDecoder>,
85 );
86 m.insert(
87 FORMAT_OTLP_LOGS,
88 Arc::new(OtelLogsBlockDecoder) as Arc<dyn BlockObjectDecoder>,
89 );
90 m.insert(
91 FORMAT_OTLP_METRICS,
92 Arc::new(OtelMetricsBlockDecoder) as Arc<dyn BlockObjectDecoder>,
93 );
94 m.insert(
95 FORMAT_OTLP_TRACES,
96 Arc::new(OtelTracesBlockDecoder) as Arc<dyn BlockObjectDecoder>,
97 );
98 Arc::new(m)
99}