Skip to content

Commit 21a766d

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

File tree

2 files changed

+150
-10
lines changed

2 files changed

+150
-10
lines changed

plugins/filter_grep/grep.c

Lines changed: 140 additions & 8 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,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 */
154250
static inline int grep_filter_data(msgpack_object map, struct grep_ctx *ctx)
155251
{
@@ -161,18 +257,24 @@ 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

164-
ret = flb_ra_regex_match(rule->ra, map, rule->regex, NULL);
165-
if (ret <= 0) { /* no match */
166-
if (rule->type == GREP_REGEX) {
260+
if (is_numeric_type(rule->type)) {
261+
if (numeric_validation(rule, map) == GREP_RET_EXCLUDE) {
167262
return GREP_RET_EXCLUDE;
168263
}
169-
}
170-
else {
171-
if (rule->type == GREP_EXCLUDE) {
172-
return GREP_RET_EXCLUDE;
264+
} else {
265+
ret = flb_ra_regex_match(rule->ra, map, rule->regex, NULL);
266+
if (ret <= 0) { /* no match */
267+
if (rule->type == GREP_REGEX) {
268+
return GREP_RET_EXCLUDE;
269+
}
173270
}
174271
else {
175-
return GREP_RET_KEEP;
272+
if (rule->type == GREP_EXCLUDE) {
273+
return GREP_RET_EXCLUDE;
274+
}
275+
else {
276+
return GREP_RET_KEEP;
277+
}
176278
}
177279
}
178280
}
@@ -301,6 +403,36 @@ static struct flb_config_map config_map[] = {
301403
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
302404
"Exclude records in which the content of KEY matches the regular expression."
303405
},
406+
{
407+
FLB_CONFIG_MAP_STR, "number_equal", NULL,
408+
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
409+
"Keep records in which the content of KEY is EQUAL to a number."
410+
},
411+
{
412+
FLB_CONFIG_MAP_STR, "number_not_equal", NULL,
413+
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
414+
"Keep records in which the content of KEY is NOT EQUAL to a number."
415+
},
416+
{
417+
FLB_CONFIG_MAP_STR, "number_less_than", NULL,
418+
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
419+
"Keep records in which the content of KEY is LESS THEN a number."
420+
},
421+
{
422+
FLB_CONFIG_MAP_STR, "number_less_than_or_equal", NULL,
423+
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
424+
"Keep records in which the content of KEY is LESS THEN or EQUAL to a number."
425+
},
426+
{
427+
FLB_CONFIG_MAP_STR, "number_greater_than", NULL,
428+
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
429+
"Keep records in which the content of KEY is GREATHER THAN a number."
430+
},
431+
{
432+
FLB_CONFIG_MAP_STR, "number_greater_than_or_equal", NULL,
433+
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
434+
"Keep records in which the content of KEY is GREATHER THAN OR EQUAL to a number."
435+
},
304436
{0}
305437
};
306438

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)