Skip to content

Commit 09bb70b

Browse files
authored
[condense_attributes_processor] Add logging (open-telemetry#2083)
Related to open-telemetry#1706 # Changes * Adds logging in `condense_attributes_processor` similar to what we have in `recordset_kql_processor`
1 parent a99326b commit 09bb70b

2 files changed

Lines changed: 137 additions & 80 deletions

File tree

  • rust/otap-dataflow/crates/otap/src/experimental

rust/otap-dataflow/crates/otap/src/experimental/condense_attributes_processor/mod.rs

Lines changed: 137 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,20 @@ use linkme::distributed_slice;
1919
use otap_df_config::SignalType;
2020
use otap_df_config::error::Error as ConfigError;
2121
use otap_df_config::node::NodeUserConfig;
22+
use otap_df_engine::ConsumerEffectHandlerExtension;
2223
use otap_df_engine::config::ProcessorConfig;
2324
use otap_df_engine::context::PipelineContext;
24-
use otap_df_engine::error::{Error, ProcessorErrorKind};
25+
use otap_df_engine::control::NackMsg;
26+
use otap_df_engine::error::Error;
2527
use otap_df_engine::local::processor as local;
2628
use otap_df_engine::message::Message;
2729
use otap_df_engine::node::NodeId;
2830
use otap_df_engine::processor::ProcessorWrapper;
29-
use otap_df_pdata::OtapArrowRecords;
3031
use otap_df_pdata::encode::record::attributes::StrKeysAttributesRecordBatchBuilder;
3132
use otap_df_pdata::otlp::attributes::AttributeValueType;
3233
use otap_df_pdata::proto::opentelemetry::arrow::v1::ArrowPayloadType;
3334
use otap_df_pdata::schema::consts;
35+
use otap_df_pdata::{OtapArrowRecords, OtapPayload};
3436
use serde_json::Value;
3537
use std::collections::{HashMap, HashSet};
3638
use std::sync::Arc;
@@ -57,59 +59,8 @@ pub struct Config {
5759
exclude_keys: Option<HashSet<String>>,
5860
}
5961

60-
/// Processor that condenses multiple attributes into a single attribute based on predefined rules.
61-
pub struct CondenseAttributesProcessor {
62-
config: Config,
63-
rows_to_preserve: Vec<usize>,
64-
}
65-
66-
fn engine_err(msg: &str) -> Error {
67-
Error::PdataConversionError {
68-
error: msg.to_string(),
69-
}
70-
}
71-
72-
/// Factory function to create a Condense Attributes processor
73-
pub fn create_condense_attributes_processor(
74-
_: PipelineContext,
75-
node: NodeId,
76-
node_config: Arc<NodeUserConfig>,
77-
processor_config: &ProcessorConfig,
78-
) -> Result<ProcessorWrapper<OtapPdata>, ConfigError> {
79-
Ok(ProcessorWrapper::local(
80-
CondenseAttributesProcessor::from_config(&node_config.config)?,
81-
node,
82-
node_config,
83-
processor_config,
84-
))
85-
}
86-
87-
/// Register CondenseAttributesProcessor as an OTAP processor factory
88-
#[allow(unsafe_code)]
89-
#[distributed_slice(OTAP_PROCESSOR_FACTORIES)]
90-
pub static CONDENSE_ATTRIBUTES_PROCESSOR_FACTORY: otap_df_engine::ProcessorFactory<OtapPdata> =
91-
otap_df_engine::ProcessorFactory {
92-
name: CONDENSE_ATTRIBUTES_PROCESSOR_URN,
93-
create: |pipeline_ctx: PipelineContext,
94-
node: NodeId,
95-
node_config: Arc<NodeUserConfig>,
96-
proc_cfg: &ProcessorConfig| {
97-
create_condense_attributes_processor(pipeline_ctx, node, node_config, proc_cfg)
98-
},
99-
wiring_contract: otap_df_engine::wiring_contract::WiringContract::UNRESTRICTED,
100-
};
101-
102-
impl CondenseAttributesProcessor {
103-
/// Creates a new CondenseAttributesProcessor instance
104-
#[must_use]
105-
pub fn new(config: Config) -> Self {
106-
Self {
107-
config,
108-
rows_to_preserve: Vec::new(),
109-
}
110-
}
111-
112-
/// Creates a new CondenseAttributesProcessor instance from configuration
62+
impl Config {
63+
/// Creates a new Config instance from configuration
11364
pub fn from_config(config: &Value) -> Result<Self, ConfigError> {
11465
let destination_key = config
11566
.get("destination_key")
@@ -193,12 +144,74 @@ impl CondenseAttributesProcessor {
193144
}
194145
}
195146

196-
Ok(Self::new(Config {
147+
Ok(Self {
197148
destination_key,
198149
delimiter,
199150
source_keys,
200151
exclude_keys,
201-
}))
152+
})
153+
}
154+
}
155+
156+
/// Processor that condenses multiple attributes into a single attribute based on predefined rules.
157+
pub struct CondenseAttributesProcessor {
158+
config: Config,
159+
rows_to_preserve: Vec<usize>,
160+
}
161+
162+
fn engine_err(msg: &str) -> Error {
163+
Error::PdataConversionError {
164+
error: msg.to_string(),
165+
}
166+
}
167+
168+
/// Factory function to create a Condense Attributes processor
169+
pub fn create_condense_attributes_processor(
170+
_: PipelineContext,
171+
node: NodeId,
172+
node_config: Arc<NodeUserConfig>,
173+
processor_config: &ProcessorConfig,
174+
) -> Result<ProcessorWrapper<OtapPdata>, ConfigError> {
175+
let processor = CondenseAttributesProcessor::from_config(&node_config.config)?;
176+
177+
otap_df_telemetry::otel_info!("condense_attributes_processor.ready");
178+
179+
Ok(ProcessorWrapper::local(
180+
processor,
181+
node,
182+
node_config,
183+
processor_config,
184+
))
185+
}
186+
187+
/// Register CondenseAttributesProcessor as an OTAP processor factory
188+
#[allow(unsafe_code)]
189+
#[distributed_slice(OTAP_PROCESSOR_FACTORIES)]
190+
pub static CONDENSE_ATTRIBUTES_PROCESSOR_FACTORY: otap_df_engine::ProcessorFactory<OtapPdata> =
191+
otap_df_engine::ProcessorFactory {
192+
name: CONDENSE_ATTRIBUTES_PROCESSOR_URN,
193+
create: |pipeline_ctx: PipelineContext,
194+
node: NodeId,
195+
node_config: Arc<NodeUserConfig>,
196+
proc_cfg: &ProcessorConfig| {
197+
create_condense_attributes_processor(pipeline_ctx, node, node_config, proc_cfg)
198+
},
199+
wiring_contract: otap_df_engine::wiring_contract::WiringContract::UNRESTRICTED,
200+
};
201+
202+
impl CondenseAttributesProcessor {
203+
/// Creates a new CondenseAttributesProcessor instance
204+
#[must_use]
205+
pub fn new(config: Config) -> Self {
206+
Self {
207+
config,
208+
rows_to_preserve: Vec::new(),
209+
}
210+
}
211+
212+
/// Creates a new CondenseAttributesProcessor instance from configuration
213+
pub fn from_config(config: &Value) -> Result<Self, ConfigError> {
214+
Ok(Self::new(Config::from_config(config)?))
202215
}
203216

204217
/// Condenses attributes in the given record batch according to the processor configuration.
@@ -531,34 +544,79 @@ impl local::Processor<OtapPdata> for CondenseAttributesProcessor {
531544
effect_handler: &mut local::EffectHandler<OtapPdata>,
532545
) -> Result<(), Error> {
533546
match msg {
534-
Message::Control(_control) => Ok(()),
547+
Message::Control(control_msg) => {
548+
use otap_df_engine::control::NodeControlMsg;
549+
match control_msg {
550+
NodeControlMsg::Config { config } => {
551+
match Config::from_config(&config) {
552+
Ok(new_config) => {
553+
otap_df_telemetry::otel_info!(
554+
"condense_attributes_processor.reconfigured"
555+
);
556+
self.config = new_config;
557+
}
558+
Err(e) => {
559+
otap_df_telemetry::otel_warn!(
560+
"condense_attributes_processor.reconfigure_error",
561+
message = %e
562+
);
563+
}
564+
}
565+
Ok(())
566+
}
567+
_ => Ok(()),
568+
}
569+
}
535570
Message::PData(pdata) => {
536571
let signal = pdata.signal_type();
537572
let (context, payload) = pdata.into_parts();
538573

539574
let mut records: OtapArrowRecords = payload.try_into()?;
540575

541-
let condensed_records: OtapArrowRecords =
542-
match signal {
543-
SignalType::Logs => match self.condense(&mut records) {
544-
// TODO: Add instrumentation for condensed count
545-
Ok(_condensed) => records,
546-
Err(e) => return Err(e),
547-
},
548-
_ => return Err(Error::ProcessorError {
549-
processor: effect_handler.processor_id(),
550-
kind: ProcessorErrorKind::Other,
551-
error:
552-
"CondenseAttributesProcessor only supported for SignalType 'Logs'"
553-
.to_string(),
554-
source_detail: String::new(),
555-
}),
556-
};
557-
558-
effect_handler
559-
.send_message(OtapPdata::new(context, condensed_records.into()))
560-
.await?;
561-
Ok(())
576+
let input_items = records.num_items() as u64;
577+
578+
otap_df_telemetry::otel_debug!(
579+
"condense_attributes_processor.processing",
580+
input_items
581+
);
582+
583+
let result = match signal {
584+
SignalType::Logs => self.condense(&mut records),
585+
_ => Err(Error::InternalError {
586+
message: "CondenseAttributesProcessor only supported for SignalType 'Logs'"
587+
.to_string(),
588+
}),
589+
};
590+
591+
match result {
592+
Ok(condensed) => {
593+
otap_df_telemetry::otel_debug!(
594+
"condense_attributes_processor.success",
595+
input_items,
596+
output_items = condensed
597+
);
598+
effect_handler
599+
.send_message(OtapPdata::new(context, records.into()))
600+
.await?;
601+
Ok(())
602+
}
603+
Err(e) => {
604+
let message = e.to_string();
605+
otap_df_telemetry::otel_error!(
606+
"condense_attributes_processor.failure",
607+
input_items,
608+
message,
609+
);
610+
611+
effect_handler
612+
.notify_nack(NackMsg::new(
613+
message,
614+
OtapPdata::new(context, OtapPayload::empty(SignalType::Logs)),
615+
))
616+
.await?;
617+
Err(e)
618+
}
619+
}
562620
}
563621
}
564622
}

rust/otap-dataflow/crates/otap/src/experimental/recordset_kql_processor/processor.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ impl Processor<OtapPdata> for RecordsetKqlProcessor {
286286
}
287287
Ok(())
288288
}
289-
NodeControlMsg::Shutdown { .. } => Ok(()),
290289
_ => Ok(()),
291290
}
292291
}

0 commit comments

Comments
 (0)