Skip to content

Commit 58b4b23

Browse files
committed
filter_grep: grep with arithmetic operators
Signed-off-by: Marcos Diez <[email protected]>
1 parent 487a054 commit 58b4b23

File tree

2 files changed

+132
-2
lines changed

2 files changed

+132
-2
lines changed

plugins/filter_grep/grep.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,22 @@
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+
3749
static 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 */
154242
static 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

plugins/filter_grep/grep.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,15 @@
2626
#include <fluent-bit/flb_record_accessor.h>
2727

2828
/* rule types */
29-
#define GREP_REGEX 1
30-
#define GREP_EXCLUDE 2
29+
#define GREP_REGEX 1
30+
#define GREP_EXCLUDE 2
31+
#define GREP_NUMBER_EQUAL 3
32+
#define GREP_NUMBER_NOT_EQUAL 4
33+
#define GREP_NUMBER_LESS_THAN 5
34+
#define GREP_NUMBER_LESS_THAN_OR_EQUAL 6
35+
#define GREP_NUMBER_GREATER_THAN 7
36+
#define GREP_NUMBER_GREATER_THAN_OR_EQUAL 8
37+
3138

3239
/* actions */
3340
#define GREP_RET_KEEP 0
@@ -42,6 +49,7 @@ struct grep_rule {
4249
int type;
4350
flb_sds_t field;
4451
char *regex_pattern;
52+
double numeric_value;
4553
struct flb_regex *regex;
4654
struct flb_record_accessor *ra;
4755
struct mk_list _head;

0 commit comments

Comments
 (0)