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,48 @@ 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+
206+ if (value_obj -> type == FLB_RA_BOOL ){
207+ value = value_obj -> val .boolean ;
208+ }
209+ else if (value_obj -> type == FLB_RA_INT ){
210+ value = value_obj -> val .i64 ;
211+ }
212+ else if (value_obj -> type == FLB_RA_FLOAT ){
213+ value = value_obj -> val .f64 ;
214+ }
215+ else {
216+ // non numeric type
217+ return GREP_RET_EXCLUDE ;
218+ }
219+
220+ switch (rule -> type ){
221+ case GREP_NUMBER_EQUAL :
222+ // we can't compare floats
223+ return abs (value - rule -> numeric_value ) < 0.0001 ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
224+ case GREP_NUMBER_NOT_EQUAL :
225+ return value != rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
226+ case GREP_NUMBER_LESS_THAN :
227+ return value < rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
228+ case GREP_NUMBER_LESS_THAN_OR_EQUAL :
229+ return value <= rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
230+ case GREP_NUMBER_GREATER_THAN :
231+ return value > rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
232+ case GREP_NUMBER_GREATER_THAN_OR_EQUAL :
233+ return value >= rule -> numeric_value ? GREP_RET_KEEP : GREP_RET_EXCLUDE ;
234+ default :
235+ return GREP_RET_EXCLUDE ;
236+ }
237+ return GREP_RET_EXCLUDE ;
238+ }
239+
240+
153241/* Given a msgpack record, do some filter action based on the defined rules */
154242static inline int grep_filter_data (msgpack_object map , struct grep_ctx * ctx )
155243{
@@ -161,6 +249,10 @@ static inline int grep_filter_data(msgpack_object map, struct grep_ctx *ctx)
161249 mk_list_foreach (head , & ctx -> rules ) {
162250 rule = mk_list_entry (head , struct grep_rule , _head );
163251
252+ if (is_numeric_type (rule -> type )){
253+ return numeric_validation (rule , map );
254+ }
255+
164256 ret = flb_ra_regex_match (rule -> ra , map , rule -> regex , NULL );
165257 if (ret <= 0 ) { /* no match */
166258 if (rule -> type == GREP_REGEX ) {
@@ -301,6 +393,36 @@ static struct flb_config_map config_map[] = {
301393 FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
302394 "Exclude records in which the content of KEY matches the regular expression."
303395 },
396+ {
397+ FLB_CONFIG_MAP_STR , "number_equal" , NULL ,
398+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
399+ "Keep records in which the content of KEY is EQUAL to a number."
400+ },
401+ {
402+ FLB_CONFIG_MAP_STR , "number_not_equal" , NULL ,
403+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
404+ "Keep records in which the content of KEY is NOT EQUAL to a number."
405+ },
406+ {
407+ FLB_CONFIG_MAP_STR , "number_less_than" , NULL ,
408+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
409+ "Keep records in which the content of KEY is LESS THEN a number."
410+ },
411+ {
412+ FLB_CONFIG_MAP_STR , "number_less_than_or_equal" , NULL ,
413+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
414+ "Keep records in which the content of KEY is LESS THEN or EQUAL to a number."
415+ },
416+ {
417+ FLB_CONFIG_MAP_STR , "number_greater_than" , NULL ,
418+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
419+ "Keep records in which the content of KEY is GREATHER THAN a number."
420+ },
421+ {
422+ FLB_CONFIG_MAP_STR , "number_greater_than_or_equal" , NULL ,
423+ FLB_CONFIG_MAP_MULT , FLB_FALSE , 0 ,
424+ "Keep records in which the content of KEY is GREATHER THAN OR EQUAL to a number."
425+ },
304426 {0 }
305427};
306428
0 commit comments