diff --git a/lib/filterx/CMakeLists.txt b/lib/filterx/CMakeLists.txt index 3db0f51b14..73c85e6ad2 100644 --- a/lib/filterx/CMakeLists.txt +++ b/lib/filterx/CMakeLists.txt @@ -10,8 +10,11 @@ set(FILTERX_HEADERS filterx/expr-setattr.h filterx/expr-set-subscript.h filterx/expr-template.h + filterx/expr-drop.h + filterx/expr-done.h filterx/filterx-config.h filterx/filterx-eval.h + filterx/filterx-error.h filterx/filterx-expr.h filterx/filterx-globals.h filterx/filterx-object.h @@ -64,8 +67,11 @@ set(FILTERX_SOURCES filterx/expr-setattr.c filterx/expr-set-subscript.c filterx/expr-template.c + filterx/expr-drop.c + filterx/expr-done.c filterx/filterx-config.c filterx/filterx-eval.c + filterx/filterx-error.c filterx/filterx-expr.c filterx/filterx-globals.c filterx/filterx-object.c diff --git a/lib/filterx/Makefile.am b/lib/filterx/Makefile.am index 7cd6b732e9..872396548e 100644 --- a/lib/filterx/Makefile.am +++ b/lib/filterx/Makefile.am @@ -15,11 +15,14 @@ filterxinclude_HEADERS = \ lib/filterx/expr-plus.h \ lib/filterx/expr-variable.h \ lib/filterx/expr-comparison.h \ + lib/filterx/expr-drop.h \ + lib/filterx/expr-done.h \ lib/filterx/filterx-object.h \ lib/filterx/filterx-weakrefs.h \ lib/filterx/object-primitive.h \ lib/filterx/filterx-scope.h \ lib/filterx/filterx-eval.h \ + lib/filterx/filterx-error.h \ lib/filterx/object-extractor.h \ lib/filterx/object-json.h \ lib/filterx/object-json-internal.h \ @@ -68,11 +71,14 @@ filterx_sources = \ lib/filterx/expr-plus.c \ lib/filterx/expr-variable.c \ lib/filterx/expr-comparison.c \ + lib/filterx/expr-drop.c \ + lib/filterx/expr-done.c \ lib/filterx/filterx-object.c \ lib/filterx/filterx-weakrefs.c \ lib/filterx/object-primitive.c \ lib/filterx/filterx-scope.c \ lib/filterx/filterx-eval.c \ + lib/filterx/filterx-error.c \ lib/filterx/object-extractor.c \ lib/filterx/object-json.c \ lib/filterx/object-json-object.c \ diff --git a/lib/filterx/expr-compound.c b/lib/filterx/expr-compound.c index 187c7cc061..0956ec36b7 100644 --- a/lib/filterx/expr-compound.c +++ b/lib/filterx/expr-compound.c @@ -84,6 +84,11 @@ _eval_exprs(FilterXCompoundExpr *self, FilterXObject **result) for (gint i = 0; i < self->exprs->len; i++) { filterx_object_unref(*result); + FilterXEvalContext *context = filterx_eval_get_context(); + + if (G_UNLIKELY(context->eval_control_modifier == FXC_DROP || context->eval_control_modifier == FXC_DONE)) + /* code flow modifier detected, short circuiting */ + return TRUE; FilterXExpr *expr = g_ptr_array_index(self->exprs, i); if (!_eval_expr(expr, result)) diff --git a/lib/filterx/expr-done.c b/lib/filterx/expr-done.c new file mode 100644 index 0000000000..8070f796fa --- /dev/null +++ b/lib/filterx/expr-done.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Axoflow + * Copyright (c) 2024 Szilard Parrag + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + + +#include "filterx/expr-done.h" +#include "filterx/filterx-eval.h" +#include "filterx/object-primitive.h" + +static FilterXObject * +_eval(FilterXExpr *s) +{ + FilterXEvalContext *context = filterx_eval_get_context(); + context->eval_control_modifier = FXC_DONE; + + return filterx_boolean_new(TRUE); +} + +FilterXExpr * +filterx_expr_done(void) +{ + FilterXExpr *self = g_new0(FilterXExpr, 1); + filterx_expr_init_instance(self); + self->eval = _eval; + + return self; +} diff --git a/lib/filterx/expr-done.h b/lib/filterx/expr-done.h new file mode 100644 index 0000000000..35a4112965 --- /dev/null +++ b/lib/filterx/expr-done.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Axoflow + * Copyright (c) 2024 Szilard Parrag + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#ifndef FILTERX_FUNC_DONE_H_INCLUDED +#define FILTERX_FUNC_DONE_H_INCLUDED + +#include "filterx/expr-function.h" + +FilterXExpr *filterx_expr_done(void); + +#endif diff --git a/lib/filterx/expr-drop.c b/lib/filterx/expr-drop.c new file mode 100644 index 0000000000..feb8457b82 --- /dev/null +++ b/lib/filterx/expr-drop.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Axoflow + * Copyright (c) 2024 Szilard Parrag + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#include "filterx/expr-drop.h" +#include "filterx/filterx-eval.h" +#include "filterx/object-primitive.h" + +static FilterXObject * +_eval(FilterXExpr *s) +{ + FilterXEvalContext *context = filterx_eval_get_context(); + context->eval_control_modifier = FXC_DROP; + + return filterx_boolean_new(TRUE); +} + +FilterXExpr * +filterx_expr_drop_msg(void) +{ + FilterXExpr *self = g_new0(FilterXExpr, 1); + filterx_expr_init_instance(self); + self->eval = _eval; + + return self; +} diff --git a/lib/filterx/expr-drop.h b/lib/filterx/expr-drop.h new file mode 100644 index 0000000000..f448ce6380 --- /dev/null +++ b/lib/filterx/expr-drop.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Axoflow + * Copyright (c) 2024 Szilard Parrag + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#ifndef FILTERX_EXPR_DROP_H_INCLUDED +#define FILTERX_EXPR_DROP_H_INCLUDED +#include "filterx/expr-function.h" + +FilterXExpr *filterx_expr_drop_msg(void); + +#endif diff --git a/lib/filterx/filterx-error.c b/lib/filterx/filterx-error.c new file mode 100644 index 0000000000..0d52f57e2b --- /dev/null +++ b/lib/filterx/filterx-error.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 Balazs Scheidler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#include "filterx/filterx-error.h" +#include "scratch-buffers.h" + +void +filterx_error_clear(FilterXError *error) +{ + filterx_object_unref(error->object); + if (error->free_info) + g_free(error->info); + memset(error, 0, sizeof(*error)); +} + +EVTTAG * +filterx_error_format(FilterXError *error) +{ + + if (!error->message) + return evt_tag_str("error", "Error information unset"); + + const gchar *extra_info = NULL; + + if (error->info) + { + extra_info = error->info; + } + else if (error->object) + { + GString *buf = scratch_buffers_alloc(); + + if (!filterx_object_repr(error->object, buf)) + { + LogMessageValueType t; + if (!filterx_object_marshal(error->object, buf, &t)) + g_assert_not_reached(); + } + extra_info = buf->str; + } + + return evt_tag_printf("error", "%s%s%s", + error->message, + extra_info ? ": " : "", + extra_info ? : ""); +} + +EVTTAG * +filterx_error_format_location(FilterXError *error) +{ + return filterx_expr_format_location_tag(error->expr); +} + +void +filterx_error_set_values(FilterXError *error, const gchar *message, FilterXExpr *expr, FilterXObject *object) +{ + error->message = message; + error->expr = expr; + error->object = filterx_object_ref(object); +} + +void +filterx_error_set_info(FilterXError *error, gchar *info, gboolean free_info) +{ + error->info = info; + error->free_info = free_info; +} diff --git a/lib/filterx/filterx-error.h b/lib/filterx/filterx-error.h new file mode 100644 index 0000000000..51ff708e8c --- /dev/null +++ b/lib/filterx/filterx-error.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Balazs Scheidler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + + +#ifndef FILTERX_ERROR_H_INCLUDED +#define FILTERX_ERROR_H_INCLUDED + +#include "filterx/filterx-scope.h" +#include "filterx/filterx-expr.h" +#include "template/eval.h" + +typedef struct _FilterXError +{ + const gchar *message; + FilterXExpr *expr; + FilterXObject *object; + gchar *info; + gboolean free_info; +} FilterXError; + +void filterx_error_clear(FilterXError *error); +EVTTAG *filterx_error_format(FilterXError *error); +EVTTAG *filterx_error_format_location(FilterXError *error); +void filterx_error_set_info(FilterXError *error, gchar *info, gboolean free_info); +void filterx_error_set_values(FilterXError *error, const gchar *message, FilterXExpr *expr, FilterXObject *object); + + +#endif diff --git a/lib/filterx/filterx-eval.c b/lib/filterx/filterx-eval.c index 0d7ecea330..51bd845ead 100644 --- a/lib/filterx/filterx-eval.c +++ b/lib/filterx/filterx-eval.c @@ -21,6 +21,7 @@ * */ #include "filterx/filterx-eval.h" +#include "filterx/filterx-error.h" #include "filterx/filterx-expr.h" #include "logpipe.h" #include "scratch-buffers.h" @@ -54,15 +55,6 @@ filterx_eval_set_context(FilterXEvalContext *context) eval_context = context; } -static void -filterx_eval_clear_error(FilterXError *error) -{ - filterx_object_unref(error->object); - if (error->free_info) - g_free(error->info); - memset(error, 0, sizeof(*error)); -} - void filterx_eval_push_error(const gchar *message, FilterXExpr *expr, FilterXObject *object) { @@ -70,11 +62,8 @@ filterx_eval_push_error(const gchar *message, FilterXExpr *expr, FilterXObject * if (context) { - filterx_eval_clear_error(&context->error); - context->error.message = message; - context->error.expr = expr; - context->error.object = filterx_object_ref(object); - context->error.info = NULL; + filterx_error_clear(&context->error); + filterx_error_set_values(&context->error, message, expr, object); } } @@ -86,12 +75,9 @@ filterx_eval_push_error_info(const gchar *message, FilterXExpr *expr, gchar *inf if (context) { - filterx_eval_clear_error(&context->error); - context->error.message = message; - context->error.expr = expr; - context->error.object = NULL; - context->error.info = info; - context->error.free_info = free_info; + filterx_error_clear(&context->error); + filterx_error_set_values(&context->error, message, expr, NULL); + filterx_error_set_info(&context->error, info, free_info); } else { @@ -105,7 +91,7 @@ filterx_eval_clear_errors(void) { FilterXEvalContext *context = filterx_eval_get_context(); - filterx_eval_clear_error(&context->error); + filterx_error_clear(&context->error); } const gchar * @@ -121,32 +107,7 @@ filterx_format_last_error(void) { FilterXEvalContext *context = filterx_eval_get_context(); - if (!context->error.message) - return evt_tag_str("error", "Error information unset"); - - const gchar *extra_info = NULL; - - if (context->error.info) - { - extra_info = context->error.info; - } - else if (context->error.object) - { - GString *buf = scratch_buffers_alloc(); - - if (!filterx_object_repr(context->error.object, buf)) - { - LogMessageValueType t; - if (!filterx_object_marshal(context->error.object, buf, &t)) - g_assert_not_reached(); - } - extra_info = buf->str; - } - - return evt_tag_printf("error", "%s%s%s", - context->error.message, - extra_info ? ": " : "", - extra_info ? : ""); + return filterx_error_format(&context->error); } EVTTAG * @@ -154,7 +115,7 @@ filterx_format_last_error_location(void) { FilterXEvalContext *context = filterx_eval_get_context(); - return filterx_expr_format_location_tag(context->error.expr); + return filterx_error_format_location(&context->error); } @@ -188,12 +149,12 @@ filterx_eval_store_weak_ref(FilterXObject *object) } } -gboolean +FilterXEvalResult filterx_eval_exec(FilterXEvalContext *context, FilterXExpr *expr, LogMessage *msg) { context->msgs = &msg; context->num_msg = 1; - gboolean success = FALSE; + FilterXEvalResult result = FXE_FAILURE; FilterXObject *res = filterx_expr_eval(expr); if (!res) @@ -204,12 +165,16 @@ filterx_eval_exec(FilterXEvalContext *context, FilterXExpr *expr, LogMessage *ms filterx_eval_clear_errors(); goto fail; } - success = filterx_object_truthy(res); + + if (G_UNLIKELY(context->eval_control_modifier == FXC_DROP)) + result = FXE_DROP; + else if (filterx_object_truthy(res)) + result = FXE_SUCCESS; filterx_object_unref(res); /* NOTE: we only store the results into the message if the entire evaluation was successful */ fail: filterx_scope_set_dirty(context->scope); - return success; + return result; } void @@ -233,6 +198,7 @@ filterx_eval_init_context(FilterXEvalContext *context, FilterXEvalContext *previ context->weak_refs = g_ptr_array_new_with_free_func((GDestroyNotify) filterx_object_unref); context->previous_context = previous_context; + context->eval_control_modifier = FXC_NOTSET; filterx_eval_set_context(context); } @@ -244,3 +210,25 @@ filterx_eval_deinit_context(FilterXEvalContext *context) filterx_scope_unref(context->scope); filterx_eval_set_context(context->previous_context); } + +EVTTAG * +filterx_format_eval_result(FilterXEvalResult result) +{ + const gchar *eval_result = NULL; + switch (result) + { + case FXE_SUCCESS: + eval_result = g_strdup("matched"); + break; + case FXE_DROP: + eval_result = g_strdup("explicitly dropped"); + break; + case FXE_FAILURE: + eval_result = g_strdup("unmatched"); + break; + default: + g_assert_not_reached(); + break; + } + return evt_tag_printf("result", "%s", eval_result); +} diff --git a/lib/filterx/filterx-eval.h b/lib/filterx/filterx-eval.h index e923c3777d..ddccbcbf2a 100644 --- a/lib/filterx/filterx-eval.h +++ b/lib/filterx/filterx-eval.h @@ -25,16 +25,24 @@ #include "filterx/filterx-scope.h" #include "filterx/filterx-expr.h" +#include "filterx/filterx-error.h" #include "template/eval.h" -typedef struct _FilterXError + +typedef enum _FilterXEvalResult +{ + FXE_SUCCESS, + FXE_FAILURE, + FXE_DROP, +} FilterXEvalResult; + + +typedef enum _FilterXEvalControl { - const gchar *message; - FilterXExpr *expr; - FilterXObject *object; - gchar *info; - gboolean free_info; -} FilterXError; + FXC_NOTSET, + FXC_DROP, + FXC_DONE +} FilterXEvalControl; typedef struct _FilterXEvalContext FilterXEvalContext; struct _FilterXEvalContext @@ -45,6 +53,7 @@ struct _FilterXEvalContext FilterXError error; LogTemplateEvalOptions template_eval_options; GPtrArray *weak_refs; + FilterXEvalControl eval_control_modifier; FilterXEvalContext *previous_context; }; @@ -53,12 +62,13 @@ FilterXScope *filterx_eval_get_scope(void); void filterx_eval_push_error(const gchar *message, FilterXExpr *expr, FilterXObject *object); void filterx_eval_push_error_info(const gchar *message, FilterXExpr *expr, gchar *info, gboolean free_info); void filterx_eval_set_context(FilterXEvalContext *context); -gboolean filterx_eval_exec(FilterXEvalContext *context, FilterXExpr *expr, LogMessage *msg); +FilterXEvalResult filterx_eval_exec(FilterXEvalContext *context, FilterXExpr *expr, LogMessage *msg); void filterx_eval_sync_scope_and_message(FilterXScope *scope, LogMessage *msg); const gchar *filterx_eval_get_last_error(void); EVTTAG *filterx_format_last_error(void); EVTTAG *filterx_format_last_error_location(void); void filterx_eval_clear_errors(void); +EVTTAG *filterx_format_eval_result(FilterXEvalResult result); void filterx_eval_store_weak_ref(FilterXObject *object); diff --git a/lib/filterx/filterx-grammar.ym b/lib/filterx/filterx-grammar.ym index b7c8c2a292..4fcf6819f1 100644 --- a/lib/filterx/filterx-grammar.ym +++ b/lib/filterx/filterx-grammar.ym @@ -55,6 +55,8 @@ #include "filterx/expr-plus.h" #include "filterx/expr-null-coalesce.h" #include "filterx/expr-plus-generator.h" +#include "filterx/expr-drop.h" +#include "filterx/expr-done.h" #include "template/templates.h" @@ -103,6 +105,8 @@ construct_template_expr(LogTemplate *template) %token KW_ENUM %token KW_ISSET %token KW_DECLARE +%token KW_DROP +%token KW_DONE %type block %type stmts @@ -362,6 +366,8 @@ expr | ternary { $$ = $1; } | default { $$ = $1; } | KW_ISSET '(' expr ')' { $$ = filterx_isset_new($3); } + | KW_DROP { $$ = filterx_expr_drop_msg(); } + | KW_DONE { $$ = filterx_expr_done(); } | regexp_match { $$ = $1; } ; diff --git a/lib/filterx/filterx-parser.c b/lib/filterx/filterx-parser.c index 6c7b77c52a..560bc4570a 100644 --- a/lib/filterx/filterx-parser.c +++ b/lib/filterx/filterx-parser.c @@ -50,6 +50,8 @@ static CfgLexerKeyword filterx_keywords[] = { "isset", KW_ISSET }, { "declare", KW_DECLARE }, + { "drop", KW_DROP }, + { "done", KW_DONE }, { CFG_KEYWORD_STOP }, }; diff --git a/lib/filterx/filterx-pipe.c b/lib/filterx/filterx-pipe.c index d57d04d1de..7fb0fa34a4 100644 --- a/lib/filterx/filterx-pipe.c +++ b/lib/filterx/filterx-pipe.c @@ -51,7 +51,7 @@ log_filterx_pipe_queue(LogPipe *s, LogMessage *msg, const LogPathOptions *path_o LogFilterXPipe *self = (LogFilterXPipe *) s; FilterXEvalContext eval_context; LogPathOptions local_path_options; - gboolean res; + FilterXEvalResult eval_res; path_options = log_path_options_chain(&local_path_options, path_options); filterx_eval_init_context(&eval_context, path_options->filterx_context); @@ -62,25 +62,33 @@ log_filterx_pipe_queue(LogPipe *s, LogMessage *msg, const LogPathOptions *path_o evt_tag_msg_reference(msg)); NVTable *payload = nv_table_ref(msg->payload); - res = filterx_eval_exec(&eval_context, self->block, msg); + eval_res = filterx_eval_exec(&eval_context, self->block, msg); msg_trace("<<<<<< filterx rule evaluation result", - evt_tag_str("result", res ? "matched" : "unmatched"), + filterx_format_eval_result(eval_res), evt_tag_str("rule", self->name), log_pipe_location_tag(s), evt_tag_int("dirty", filterx_scope_is_dirty(eval_context.scope)), evt_tag_msg_reference(msg)); local_path_options.filterx_context = &eval_context; - if (res) + switch (eval_res) { + case FXE_SUCCESS: log_pipe_forward_msg(s, msg, path_options); - } - else - { + break; + + case FXE_FAILURE: if (path_options->matched) (*path_options->matched) = FALSE; + /* FALLTHROUGH */ + case FXE_DROP: log_msg_drop(msg, path_options, AT_PROCESSED); + break; + + default: + g_assert_not_reached(); + break; } filterx_eval_deinit_context(&eval_context); diff --git a/tests/light/functional_tests/filterx/test_filterx.py b/tests/light/functional_tests/filterx/test_filterx.py index 4aff1ed4d0..d5b136dbc8 100644 --- a/tests/light/functional_tests/filterx/test_filterx.py +++ b/tests/light/functional_tests/filterx/test_filterx.py @@ -2039,3 +2039,67 @@ def test_list_range_check_out_of_range(config, syslog_ng): syslog_ng.start(config) assert file_false.get_stats()["processed"] == 1 assert file_false.read_log() == "foobar\n" + + +def test_drop(config, syslog_ng): + file_true = config.create_file_destination(file_name="dest-true.log", template="'$MSG\n'") + file_false = config.create_file_destination(file_name="dest-false.log", template="'$MSG\n'") + + raw_conf = f""" +@version: {config.get_version()} + +options {{ stats(level(1)); }}; + +source genmsg {{ + example-msg-generator(num(1) template("foo")); + example-msg-generator(num(1) template("bar")); +}}; + +destination dest_true {{ + {render_statement(file_true)}; +}}; + +destination dest_false {{ + {render_statement(file_false)}; +}}; + +log {{ + source(genmsg); + if {{ + filterx {{ {"if ($MSG =~ 'foo') {drop;};"} \n}}; + destination(dest_true); + }} else {{ + destination(dest_false); + }}; +}}; +""" + config.set_raw_config(raw_conf) + + syslog_ng.start(config) + + assert "processed" in file_true.get_stats() + assert file_true.get_stats()["processed"] == 1 + assert file_true.read_log() == 'bar\n' + assert syslog_ng.wait_for_message_in_console_log("filterx rule evaluation result; result='explicitly dropped'") != [] + + +def test_done(config, syslog_ng): + (file_true, file_false) = create_config( + config, + msg="foo", + filterx_expr_1=r""" + if ($MSG =~ 'foo') { + declare var_wont_change = true; + done; + var_wont_change = false; # This will be skipped + }; + """, + filterx_expr_2=r""" + $MSG = vars(); + """, + ) + syslog_ng.start(config) + + assert file_true.get_stats()["processed"] == 1 + assert "processed" not in file_false.get_stats() + assert file_true.read_log() == '{"MESSAGE":"foo","var_wont_change":true}\n'