3030#include <fluent-bit/flb_pack.h>
3131#include <fluent-bit/flb_regex.h>
3232#include <fluent-bit/flb_record_accessor.h>
33+ #include <fluent-bit/flb_ra_key.h>
3334#include <msgpack.h>
3435
3536#include "grep.h"
3637
38+ static inline int is_numeric_type (int type )
39+ {
40+ return
41+ type == GREP_NUMBER_EQUAL ||
42+ type == GREP_NUMBER_NOT_EQUAL ||
43+ type == GREP_NUMBER_LESS_THAN ||
44+ type == GREP_NUMBER_LESS_THAN_OR_EQUAL ||
45+ type == GREP_NUMBER_GREATER_THAN ||
46+ type == GREP_NUMBER_GREATER_THAN_OR_EQUAL ;
47+ }
48+
3749static void delete_rules (struct grep_ctx * ctx )
3850{
3951 struct mk_list * tmp ;
@@ -78,6 +90,24 @@ static int set_rules(struct grep_ctx *ctx, struct flb_filter_instance *f_ins)
7890 else if (strcasecmp (kv -> key , "exclude" ) == 0 ) {
7991 rule -> type = GREP_EXCLUDE ;
8092 }
93+ else if (strcasecmp (kv -> key , "number_equal" ) == 0 ) {
94+ rule -> type = GREP_NUMBER_EQUAL ;
95+ }
96+ else if (strcasecmp (kv -> key , "number_not_equal" ) == 0 ) {
97+ rule -> type = GREP_NUMBER_NOT_EQUAL ;
98+ }
99+ else if (strcasecmp (kv -> key , "number_less_than" ) == 0 ) {
100+ rule -> type = GREP_NUMBER_LESS_THAN ;
101+ }
102+ else if (strcasecmp (kv -> key , "number_less_than_or_equal" ) == 0 ) {
103+ rule -> type = GREP_NUMBER_LESS_THAN_OR_EQUAL ;
104+ }
105+ else if (strcasecmp (kv -> key , "number_greater_than" ) == 0 ) {
106+ rule -> type = GREP_NUMBER_GREATER_THAN ;
107+ }
108+ else if (strcasecmp (kv -> key , "number_greater_than_or_equal" ) == 0 ) {
109+ rule -> type = GREP_NUMBER_GREATER_THAN_OR_EQUAL ;
110+ }
81111 else {
82112 flb_plg_error (ctx -> ins , "unknown rule type '%s'" , kv -> key );
83113 delete_rules (ctx );
@@ -121,6 +151,22 @@ static int set_rules(struct grep_ctx *ctx, struct flb_filter_instance *f_ins)
121151 return -1 ;
122152 }
123153
154+ /* parses the numeric value if needed */
155+ if (is_numeric_type (rule -> type )) {
156+ int retval = sscanf (sentry -> value , "%lf" , & (rule -> numeric_value ));
157+ if (retval == EOF ) {
158+ /* this should not happen, for sscanf should write zero if it can parse a double */
159+ flb_plg_error (ctx -> ins ,
160+ "invalid numerical value" );
161+ delete_rules (ctx );
162+ flb_free (rule );
163+ flb_utils_split_free (split );
164+ return -1 ;
165+ }
166+ } else {
167+ rule -> numeric_value = 0 ;
168+ }
169+
124170 /* Release split */
125171 flb_utils_split_free (split );
126172
@@ -150,6 +196,56 @@ static int set_rules(struct grep_ctx *ctx, struct flb_filter_instance *f_ins)
150196 return 0 ;
151197}
152198
199+ static inline int numeric_validation (struct grep_rule * rule , msgpack_object map )
200+ {
201+ struct flb_ra_value * value_obj ;
202+ double value ;
203+
204+ value_obj = flb_ra_get_value_object (rule -> ra , map );
205+ if (!value_obj ) {
206+ return GREP_RET_EXCLUDE ;
207+ }
208+
209+ if (value_obj -> type == FLB_RA_BOOL ) {
210+ value = value_obj -> val .boolean ;
211+ }
212+ else if (value_obj -> type == FLB_RA_INT ) {
213+ value = value_obj -> val .i64 ;
214+ }
215+ else if (value_obj -> type == FLB_RA_FLOAT ) {
216+ value = value_obj -> val .f64 ;
217+ }
218+ else {
219+ if (value_obj ) {
220+ flb_ra_key_value_destroy (value_obj );
221+ }
222+ // non numeric type
223+ return GREP_RET_EXCLUDE ;
224+ }
225+ if (value_obj ) {
226+ flb_ra_key_value_destroy (value_obj );
227+ }
228+ switch (rule -> type ) {
229+ case GREP_NUMBER_EQUAL :
230+ // we can't compare floats
231+ return abs (value - rule -> numeric_value ) < 0.0001 ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
232+ case GREP_NUMBER_NOT_EQUAL :
233+ return value != rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
234+ case GREP_NUMBER_LESS_THAN :
235+ return value < rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
236+ case GREP_NUMBER_LESS_THAN_OR_EQUAL :
237+ return value <= rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
238+ case GREP_NUMBER_GREATER_THAN :
239+ return value > rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
240+ case GREP_NUMBER_GREATER_THAN_OR_EQUAL :
241+ return value >= rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
242+ default :
243+ return GREP_RET_EXCLUDE ;
244+ }
245+ return GREP_RET_EXCLUDE ;
246+ }
247+
248+
153249/* Given a msgpack record, do some filter action based on the defined rules */
154250static inline int grep_filter_data (msgpack_object map , struct grep_ctx * ctx )
155251{
@@ -161,6 +257,10 @@ static inline int grep_filter_data(msgpack_object map, struct grep_ctx *ctx)
161257 mk_list_foreach (head , & ctx -> rules ) {
162258 rule = mk_list_entry (head , struct grep_rule , _head );
163259
260+ if (is_numeric_type (rule -> type )) {
261+ return numeric_validation (rule , map );
262+ }
263+
164264 ret = flb_ra_regex_match (rule -> ra , map , rule -> regex , NULL );
165265 if (ret <= 0 ) { /* no match */
166266 if (rule -> type == GREP_REGEX ) {
@@ -301,6 +401,36 @@ static struct flb_config_map config_map[] = {
301401 FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
302402 "Exclude records in which the content of KEY matches the regular expression."
303403 },
404+ {
405+ FLB_CONFIG_MAP_STR , "number_equal" , NULL ,
406+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
407+ "Keep records in which the content of KEY is EQUAL to a number."
408+ },
409+ {
410+ FLB_CONFIG_MAP_STR , "number_not_equal" , NULL ,
411+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
412+ "Keep records in which the content of KEY is NOT EQUAL to a number."
413+ },
414+ {
415+ FLB_CONFIG_MAP_STR , "number_less_than" , NULL ,
416+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
417+ "Keep records in which the content of KEY is LESS THEN a number."
418+ },
419+ {
420+ FLB_CONFIG_MAP_STR , "number_less_than_or_equal" , NULL ,
421+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
422+ "Keep records in which the content of KEY is LESS THEN or EQUAL to a number."
423+ },
424+ {
425+ FLB_CONFIG_MAP_STR , "number_greater_than" , NULL ,
426+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
427+ "Keep records in which the content of KEY is GREATHER THAN a number."
428+ },
429+ {
430+ FLB_CONFIG_MAP_STR , "number_greater_than_or_equal" , NULL ,
431+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
432+ "Keep records in which the content of KEY is GREATHER THAN OR EQUAL to a number."
433+ },
304434 {0 }
305435};
306436
0 commit comments