Skip to content

Commit

Permalink
filterx: do not consider unmarshaling a change in value
Browse files Browse the repository at this point in the history
If we pull in a variable from the message and we need to unmarshal it
(e.g. turn FilterXMessageValue to a more specific type like FilterXString or
FilterXJSON), do not consider that a change of that variable.

Changing it in-place, or assignment of a new value should be remain to
be a change.

Signed-off-by: Balazs Scheidler <[email protected]>
  • Loading branch information
bazsi committed Jan 7, 2025
1 parent ae41725 commit 2f4a91f
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 13 deletions.
4 changes: 2 additions & 2 deletions lib/filterx/expr-variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ _update_repr(FilterXExpr *s, FilterXObject *new_repr)
FilterXVariable *variable = filterx_scope_lookup_variable(scope, self->handle);

g_assert(variable != NULL);
filterx_variable_set_value(variable, new_repr);
filterx_variable_set_value(variable, new_repr, FALSE);
}

static gboolean
Expand All @@ -130,7 +130,7 @@ _assign(FilterXExpr *s, FilterXObject *new_value)

/* this only clones mutable objects */
new_value = filterx_object_clone(new_value);
filterx_variable_set_value(variable, new_value);
filterx_variable_set_value(variable, new_value, TRUE);
filterx_object_unref(new_value);
return TRUE;
}
Expand Down
4 changes: 1 addition & 3 deletions lib/filterx/filterx-scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ _register_variable(FilterXScope *self,
* it was a new value */

filterx_variable_set_generation(v_slot, self->generation);
filterx_variable_set_value(v_slot, initial_value);
/* consider this to be unset just as an initial registration is */
filterx_variable_unassign(v_slot);
filterx_variable_set_value(v_slot, initial_value, FALSE);
}
return v_slot;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/filterx/filterx-variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,17 @@ filterx_variable_get_value(FilterXVariable *v)
}

static inline void
filterx_variable_set_value(FilterXVariable *v, FilterXObject *new_value)
filterx_variable_set_value(FilterXVariable *v, FilterXObject *new_value, gboolean assignment)
{
filterx_object_unref(v->value);
v->value = filterx_object_ref(new_value);
v->assigned = TRUE;
v->assigned = assignment;
}

static inline void
filterx_variable_unset_value(FilterXVariable *v)
{
filterx_variable_set_value(v, NULL);
filterx_variable_set_value(v, NULL, TRUE);
}

static inline gboolean
Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/func-vars.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ _load_from_dict(FilterXObject *key, FilterXObject *value, gpointer user_data)
variable = filterx_scope_register_variable(scope, variable_type, handle, NULL);

FilterXObject *cloned_value = filterx_object_clone(value);
filterx_variable_set_value(variable, cloned_value);
filterx_variable_set_value(variable, cloned_value, TRUE);
filterx_object_unref(cloned_value);

if (!variable)
Expand Down
42 changes: 38 additions & 4 deletions tests/light/functional_tests/filterx/test_filterx_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ def render_filterx_exprs(expressions):
return '\n'.join(f"filterx {{ {expr} }};" for expr in expressions)


def create_config(config, init_exprs, true_exprs=(), false_exprs=(), final_exprs=(), msg="foobar"):
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'")
file_final = config.create_file_destination(file_name="dest-final.log", template="'$MSG\n'")
def create_config(config, init_exprs, true_exprs=(), false_exprs=(), final_exprs=(), msg="foobar", template='"$MSG\n"'):
file_final = config.create_file_destination(file_name="dest-final.log", template=template)
file_true = config.create_file_destination(file_name="dest-true.log", template=template)
file_false = config.create_file_destination(file_name="dest-false.log", template=template)

preamble = f"""
@version: {config.get_version()}
Expand Down Expand Up @@ -182,6 +182,40 @@ def test_message_tied_variables_do_not_propagate_to_parallel_branches(config, sy
assert file_false.read_log() == "kecske\n"


def test_message_tied_variables_are_not_considered_changed_just_by_unmarshaling(config, syslog_ng):
(file_true, file_false, file_final) = create_config(
config, init_exprs=[
"""
# pull up the value from the message into a filterx variable
${values.json};
# cause an unmarshal into JSON
${values.json}.emb_key1;
# $foo is set to the unmarshalled version of ${values.json}
$foo = ${values.json};
""",
], init_log_exprs=[
# trigger a sync
"""
rewrite {
};
""",
],
# ${values.json} should retain to have spaces in them, since it was not actually changed, just unmarshalled
# ${foo} is reformatted from the unmarshalled value
#
# NOTE the extra spaces in the assertion below on the $foo part
template="'${values.json} -- $foo\n'"
)

syslog_ng.start(config)

assert file_true.get_stats()["processed"] == 1
assert "processed" not in file_false.get_stats()
(values_json, foo) = file_true.read_log().strip().split(' -- ')
assert values_json == """{"emb_key1": "emb_key1 value", "emb_key2": "emb_key2 value"}"""
assert foo == """{"emb_key1":"emb_key1 value","emb_key2":"emb_key2 value"}"""


def test_floating_variables_are_dropped_at_the_end_of_the_scope(config, syslog_ng):
(file_true, file_false, _) = create_config(
config, [
Expand Down

0 comments on commit 2f4a91f

Please sign in to comment.