1616 *
1717 */
1818
19+ use arrow_array:: cast:: as_string_array;
20+ use arrow_array:: RecordBatch ;
21+ use arrow_schema:: DataType ;
1922use async_trait:: async_trait;
23+ use datafusion:: arrow:: compute:: kernels:: cast;
2024use datafusion:: arrow:: datatypes:: Schema ;
2125use regex:: Regex ;
2226use serde:: { Deserialize , Serialize } ;
@@ -33,21 +37,21 @@ use crate::{storage, utils};
3337pub use self :: rule:: Rule ;
3438use self :: target:: Target ;
3539
36- #[ derive( Default , Debug , Serialize , Deserialize ) ]
40+ #[ derive( Default , Debug , serde :: Serialize , serde :: Deserialize ) ]
3741#[ serde( rename_all = "camelCase" ) ]
3842pub struct Alerts {
3943 pub version : AlertVerison ,
4044 pub alerts : Vec < Alert > ,
4145}
4246
43- #[ derive( Default , Debug , Serialize , Deserialize ) ]
47+ #[ derive( Default , Debug , serde :: Serialize , serde :: Deserialize ) ]
4448#[ serde( rename_all = "lowercase" ) ]
4549pub enum AlertVerison {
4650 #[ default]
4751 V1 ,
4852}
4953
50- #[ derive( Debug , Serialize , Deserialize ) ]
54+ #[ derive( Debug , serde :: Serialize , serde :: Deserialize ) ]
5155#[ serde( rename_all = "camelCase" ) ]
5256pub struct Alert {
5357 #[ serde( default = "crate::utils::uid::gen" ) ]
@@ -60,22 +64,29 @@ pub struct Alert {
6064}
6165
6266impl Alert {
63- pub fn check_alert ( & self , stream_name : String , event_json : & serde_json :: Value ) {
64- let resolves = self . rule . resolves ( event_json ) ;
67+ pub fn check_alert ( & self , stream_name : String , events : RecordBatch ) {
68+ let resolves = self . rule . resolves ( events . clone ( ) ) ;
6569
66- match resolves {
67- AlertState :: Listening | AlertState :: Firing => ( ) ,
68- alert_state @ ( AlertState :: SetToFiring | AlertState :: Resolved ) => {
69- let context = self . get_context ( stream_name, alert_state, & self . rule , event_json) ;
70- ALERTS_STATES
71- . with_label_values ( & [
72- context. stream . as_str ( ) ,
73- context. alert_info . alert_name . as_str ( ) ,
74- context. alert_info . alert_state . to_string ( ) . as_str ( ) ,
75- ] )
76- . inc ( ) ;
77- for target in & self . targets {
78- target. call ( context. clone ( ) ) ;
70+ for ( index, state) in resolves. into_iter ( ) . enumerate ( ) {
71+ match state {
72+ AlertState :: Listening | AlertState :: Firing => ( ) ,
73+ alert_state @ ( AlertState :: SetToFiring | AlertState :: Resolved ) => {
74+ let context = self . get_context (
75+ stream_name. clone ( ) ,
76+ alert_state,
77+ & self . rule ,
78+ events. slice ( index, 1 ) ,
79+ ) ;
80+ ALERTS_STATES
81+ . with_label_values ( & [
82+ context. stream . as_str ( ) ,
83+ context. alert_info . alert_name . as_str ( ) ,
84+ context. alert_info . alert_state . to_string ( ) . as_str ( ) ,
85+ ] )
86+ . inc ( ) ;
87+ for target in & self . targets {
88+ target. call ( context. clone ( ) ) ;
89+ }
7990 }
8091 }
8192 }
@@ -86,7 +97,7 @@ impl Alert {
8697 stream_name : String ,
8798 alert_state : AlertState ,
8899 rule : & Rule ,
89- event_json : & serde_json :: Value ,
100+ event_row : RecordBatch ,
90101 ) -> Context {
91102 let deployment_instance = format ! (
92103 "{}://{}" ,
@@ -104,7 +115,7 @@ impl Alert {
104115 stream_name,
105116 AlertInfo :: new (
106117 self . name . clone ( ) ,
107- self . message . get ( event_json ) ,
118+ self . message . get ( event_row ) ,
108119 rule. trigger_reason ( ) ,
109120 alert_state,
110121 ) ,
@@ -144,9 +155,12 @@ impl Message {
144155 }
145156
146157 // returns the message with the column name replaced with the value of the column
147- fn get ( & self , event_json : & serde_json :: Value ) -> String {
158+ fn get ( & self , event : RecordBatch ) -> String {
148159 if let Some ( column) = self . extract_column_name ( ) {
149- if let Some ( value) = event_json. get ( column) {
160+ if let Some ( value) = event. column_by_name ( column) {
161+ let arr = cast ( value, & DataType :: Utf8 ) . unwrap ( ) ;
162+ let value = as_string_array ( & arr) . value ( 0 ) ;
163+
150164 return self
151165 . message
152166 . replace ( & format ! ( "{{{column}}}" ) , value. to_string ( ) . as_str ( ) ) ;
0 commit comments