Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitrijs Goloscapovs <dmitrijs.goloscapovs@zabbix.com>2022-11-09 14:44:50 +0300
committerDmitrijs Goloscapovs <dmitrijs.goloscapovs@zabbix.com>2022-11-09 14:44:50 +0300
commitfb831f3178b898a0db64d2e7f017aae825d18533 (patch)
treef8220825cfdf8456d1325f85c68b4c07066e4531
parent689a5591eb20a54bf5c1114a9147bc8e6451d43c (diff)
parent1873100855685ae887206895a1e119b93d9905fe (diff)
........S. [ZBX-21616] fixed error due to non-existent macros in custom expressions
Merge in ZBX/zabbix from feature/ZBX-21616-6.3 to master * commit '1873100855685ae887206895a1e119b93d9905fe': ........S. [ZBX-21616] renamed define ........S. [ZBX-21616] fixed function description comment ........S. [ZBX-21616] got rid of ZBX_FALLTROUGH .......... [ZBX-21616] code style fix ........S. [ZBX-21616] fixed offseet calculation when replacing condition ids with values ........S. [ZBX-21616] added more optimizations to LLD filter processing ........S. [ZBX-21616] optimized .......... [ZBX-21616] added changelog .......... [ZBX-21616] added changelog ........S. [ZBX-21616] refactored and reimplemented parsing logics ........S. [ZBX-21616] fixed error due to non-existent macros in custom expressions
-rw-r--r--ChangeLog.d/bugfix/ZBX-216161
-rw-r--r--include/zbxdbhigh.h8
-rw-r--r--src/libs/zbxcacheconfig/dbconfig.c16
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_3010.c4
-rw-r--r--src/libs/zbxdbwrap/template_item.c4
-rw-r--r--src/zabbix_server/actions.c16
-rw-r--r--src/zabbix_server/escalator/escalator.c8
-rw-r--r--src/zabbix_server/lld/lld.c284
-rw-r--r--src/zabbix_server/service/service_manager.c6
9 files changed, 188 insertions, 159 deletions
diff --git a/ChangeLog.d/bugfix/ZBX-21616 b/ChangeLog.d/bugfix/ZBX-21616
new file mode 100644
index 00000000000..fcabe90b876
--- /dev/null
+++ b/ChangeLog.d/bugfix/ZBX-21616
@@ -0,0 +1 @@
+........S. [ZBX-21616] fixed error due to non-existent macros in custom expressions (dgoloscapov, wiper)
diff --git a/include/zbxdbhigh.h b/include/zbxdbhigh.h
index 03067c163fd..f10862719ac 100644
--- a/include/zbxdbhigh.h
+++ b/include/zbxdbhigh.h
@@ -786,10 +786,10 @@ char *zbx_get_proxy_protocol_version_str(const struct zbx_json_parse *jp);
int zbx_get_proxy_protocol_version_int(const char *version_str);
/* condition evaluation types */
-#define ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR 0
-#define ZBX_ACTION_CONDITION_EVAL_TYPE_AND 1
-#define ZBX_ACTION_CONDITION_EVAL_TYPE_OR 2
-#define ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION 3
+#define ZBX_CONDITION_EVAL_TYPE_AND_OR 0
+#define ZBX_CONDITION_EVAL_TYPE_AND 1
+#define ZBX_CONDITION_EVAL_TYPE_OR 2
+#define ZBX_CONDITION_EVAL_TYPE_EXPRESSION 3
/* condition types */
#define ZBX_CONDITION_TYPE_HOST_GROUP 0
diff --git a/src/libs/zbxcacheconfig/dbconfig.c b/src/libs/zbxcacheconfig/dbconfig.c
index 73098113be7..0785566d4e6 100644
--- a/src/libs/zbxcacheconfig/dbconfig.c
+++ b/src/libs/zbxcacheconfig/dbconfig.c
@@ -4448,7 +4448,7 @@ static void DCsync_action_conditions(zbx_dbsync_t *sync)
zbx_vector_ptr_append(&action->conditions, condition);
}
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_vector_ptr_append(&actions, action);
}
@@ -4468,7 +4468,7 @@ static void DCsync_action_conditions(zbx_dbsync_t *sync)
{
zbx_vector_ptr_remove_noorder(&action->conditions, index);
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_vector_ptr_append(&actions, action);
}
}
@@ -4488,7 +4488,7 @@ static void DCsync_action_conditions(zbx_dbsync_t *sync)
{
action = (zbx_dc_action_t *)actions.values[i];
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_vector_ptr_sort(&action->conditions, dc_compare_action_conditions_by_type);
}
@@ -4755,7 +4755,7 @@ static void DCsync_corr_conditions(zbx_dbsync_t *sync)
zbx_vector_ptr_append(&correlation->conditions, condition);
/* sort the conditions later */
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
zbx_vector_ptr_append(&correlations, correlation);
}
@@ -4777,7 +4777,7 @@ static void DCsync_corr_conditions(zbx_dbsync_t *sync)
ZBX_DEFAULT_PTR_COMPARE_FUNC)))
{
/* sort the conditions later */
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
zbx_vector_ptr_append(&correlations, correlation);
zbx_vector_ptr_remove_noorder(&correlation->conditions, index);
@@ -13349,7 +13349,7 @@ static char *dc_correlation_formula_dup(const zbx_dc_correlation_t *dc_correlati
const zbx_dc_corr_condition_t *dc_condition;
zbx_uint64_t last_id;
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == dc_correlation->evaltype || 0 ==
+ if (ZBX_CONDITION_EVAL_TYPE_EXPRESSION == dc_correlation->evaltype || 0 ==
dc_correlation->conditions.values_num)
{
return zbx_strdup(NULL, dc_correlation->formula);
@@ -13359,10 +13359,10 @@ static char *dc_correlation_formula_dup(const zbx_dc_correlation_t *dc_correlati
switch (dc_correlation->evaltype)
{
- case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
+ case ZBX_CONDITION_EVAL_TYPE_OR:
op = " or";
break;
- case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
+ case ZBX_CONDITION_EVAL_TYPE_AND:
op = " and";
break;
}
diff --git a/src/libs/zbxdbupgrade/dbupgrade_3010.c b/src/libs/zbxdbupgrade/dbupgrade_3010.c
index 5b27f3904da..8110eff3759 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_3010.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_3010.c
@@ -465,7 +465,7 @@ static int DBpatch_3010024_validate_action(zbx_uint64_t actionid, int eventsourc
DB_RESULT result;
int conditiontype, ret = ZBX_3010024_ACTION_DISABLE, value;
- /* evaltype: 0 - ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR, 1 - ZBX_ACTION_CONDITION_EVAL_TYPE_AND */
+ /* evaltype: 0 - ZBX_CONDITION_EVAL_TYPE_AND_OR, 1 - ZBX_CONDITION_EVAL_TYPE_AND */
if (evaltype != 0 && evaltype != 1)
return ret;
@@ -1045,7 +1045,7 @@ static int DBpatch_3010026(void)
index = conditionids.values_num;
DBpatch_3010026_get_conditionids(actionid, row[4], eventsource, &conditionids);
- /* evaltype: 3 - ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION */
+ /* evaltype: 3 - ZBX_CONDITION_EVAL_TYPE_EXPRESSION */
if (3 != evaltype)
continue;
diff --git a/src/libs/zbxdbwrap/template_item.c b/src/libs/zbxdbwrap/template_item.c
index 37db1c92c0a..d399cd3c040 100644
--- a/src/libs/zbxdbwrap/template_item.c
+++ b/src/libs/zbxdbwrap/template_item.c
@@ -722,7 +722,7 @@ static void update_template_lld_rule_formulas(zbx_vector_ptr_t *items, zbx_vecto
{
zbx_template_item_t *item = (zbx_template_item_t *)items->values[i];
- if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags) || ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION !=
+ if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags) || ZBX_CONDITION_EVAL_TYPE_EXPRESSION !=
item->evaltype)
{
continue;
@@ -2297,7 +2297,7 @@ static void save_template_lld_overrides(zbx_vector_ptr_t *overrides, zbx_hashset
override_conditionid, (int)override_condition->operator, override_condition->macro,
override_condition->value);
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == override->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_EXPRESSION == override->evaltype)
{
update_template_lld_formula(&override->formula,
override_condition->override_conditionid, override_conditionid);
diff --git a/src/zabbix_server/actions.c b/src/zabbix_server/actions.c
index 0fda368e4eb..a021bca13f3 100644
--- a/src/zabbix_server/actions.c
+++ b/src/zabbix_server/actions.c
@@ -2587,14 +2587,14 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
zabbix_log(LOG_LEVEL_DEBUG, "In %s() actionid:" ZBX_FS_UI64 " eventsource:%d", __func__,
action->actionid, (int)action->eventsource);
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
expression = zbx_strdup(expression, action->formula);
for (i = 0; i < action->conditions.values_num; i++)
{
condition = (zbx_condition_t *)action->conditions.values[i];
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype &&
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == action->evaltype &&
old_type == condition->conditiontype && SUCCEED == ret)
{
continue; /* short-circuit true OR condition block to the next AND condition */
@@ -2609,7 +2609,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
switch (action->evaltype)
{
- case ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR:
+ case ZBX_CONDITION_EVAL_TYPE_AND_OR:
if (old_type == condition->conditiontype) /* assume conditions are sorted by type */
{
if (SUCCEED == condition_result)
@@ -2625,7 +2625,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
}
break;
- case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
+ case ZBX_CONDITION_EVAL_TYPE_AND:
if (FAIL == condition_result) /* break if any AND condition is FALSE */
{
ret = FAIL;
@@ -2633,7 +2633,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
}
break;
- case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
+ case ZBX_CONDITION_EVAL_TYPE_OR:
if (SUCCEED == condition_result) /* break if any OR condition is TRUE */
{
ret = SUCCEED;
@@ -2642,7 +2642,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
ret = FAIL;
break;
- case ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION:
+ case ZBX_CONDITION_EVAL_TYPE_EXPRESSION:
zbx_snprintf(tmp, sizeof(tmp), "{" ZBX_FS_UI64 "}", condition->conditionid);
id_len = strlen(tmp);
@@ -2659,7 +2659,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
}
}
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
{
if (SUCCEED == zbx_evaluate(&eval_result, expression, error, sizeof(error), NULL))
ret = (SUCCEED != zbx_double_compare(eval_result, 0) ? SUCCEED : FAIL);
@@ -3053,7 +3053,7 @@ static void prepare_actions_conditions_eval(zbx_vector_ptr_t *actions, zbx_hashs
}
else
{
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
{
char search[ZBX_MAX_UINT64_LEN + 2];
char replace[ZBX_MAX_UINT64_LEN + 2];
diff --git a/src/zabbix_server/escalator/escalator.c b/src/zabbix_server/escalator/escalator.c
index 96ad3046ac7..18f3b69e7aa 100644
--- a/src/zabbix_server/escalator/escalator.c
+++ b/src/zabbix_server/escalator/escalator.c
@@ -1799,7 +1799,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
DB_ROW row;
zbx_condition_t condition;
- int ret = SUCCEED; /* SUCCEED required for ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR */
+ int ret = SUCCEED; /* SUCCEED required for ZBX_CONDITION_EVAL_TYPE_AND_OR */
int cond, exit = 0;
unsigned char old_type = 0xff;
@@ -1825,7 +1825,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
switch (evaltype)
{
- case ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR:
+ case ZBX_CONDITION_EVAL_TYPE_AND_OR:
if (old_type == condition.conditiontype) /* OR conditions */
{
if (SUCCEED == check_action_condition(event, &condition))
@@ -1841,7 +1841,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
}
old_type = condition.conditiontype;
break;
- case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
+ case ZBX_CONDITION_EVAL_TYPE_AND:
cond = check_action_condition(event, &condition);
/* Break if any of AND conditions is FALSE */
if (cond == FAIL)
@@ -1852,7 +1852,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
else
ret = SUCCEED;
break;
- case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
+ case ZBX_CONDITION_EVAL_TYPE_OR:
cond = check_action_condition(event, &condition);
/* Break if any of OR conditions is TRUE */
if (cond == SUCCEED)
diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c
index 3af8d4a0397..8e9681ac00a 100644
--- a/src/zabbix_server/lld/lld.c
+++ b/src/zabbix_server/lld/lld.c
@@ -116,7 +116,7 @@ static void lld_filter_init(lld_filter_t *filter)
{
zbx_vector_ptr_create(&filter->conditions);
filter->expression = NULL;
- filter->evaltype = ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR;
+ filter->evaltype = ZBX_CONDITION_EVAL_TYPE_AND_OR;
}
/******************************************************************************
@@ -195,7 +195,7 @@ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, const
;
DBfree_result(result);
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == filter->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == filter->evaltype)
zbx_vector_ptr_sort(&filter->conditions, lld_condition_compare_by_macro);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
@@ -210,6 +210,7 @@ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, const
* Parameters: jp_row - [IN] the lld data row *
* lld_macro_paths - [IN] use json path to extract from jp_row *
* condition - [IN] the lld filter condition *
+ * result - [OUT] the result of evaluation *
* info - [OUT] the warning description *
* *
* Return value: SUCCEED - the lld data passed filter evaluation *
@@ -217,41 +218,54 @@ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, const
* *
******************************************************************************/
static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths,
- const lld_condition_t *condition, char **info)
+ const lld_condition_t *condition, int *result, char **info)
{
char *value = NULL;
- int ret;
+ int ret = SUCCEED;
- if (SUCCEED == (ret = zbx_lld_macro_value_by_name(jp_row, lld_macro_paths, condition->macro, &value)))
+ if (SUCCEED == zbx_lld_macro_value_by_name(jp_row, lld_macro_paths, condition->macro, &value))
{
if (ZBX_CONDITION_OPERATOR_NOT_EXIST == condition->op)
{
- ret = FAIL;
+ *result = 0;
}
- else if (ZBX_CONDITION_OPERATOR_EXIST != condition->op)
+ else if (ZBX_CONDITION_OPERATOR_EXIST == condition->op)
+ {
+ *result = 1;
+ }
+ else
{
switch (regexp_match_ex(&condition->regexps, value, condition->regexp, ZBX_CASE_SENSITIVE))
{
case ZBX_REGEXP_MATCH:
- ret = (ZBX_CONDITION_OPERATOR_REGEXP == condition->op ? SUCCEED : FAIL);
+ *result = (ZBX_CONDITION_OPERATOR_REGEXP == condition->op ? 1 : 0);
break;
case ZBX_REGEXP_NO_MATCH:
- ret = (ZBX_CONDITION_OPERATOR_NOT_REGEXP == condition->op ? SUCCEED : FAIL);
+ *result = (ZBX_CONDITION_OPERATOR_NOT_REGEXP == condition->op ? 1 : 0);
+ break;
break;
default:
+ *info = zbx_strdcatf(*info, "Cannot accurately apply filter: invalid regular "
+ "expression \"%s\".\n", condition->regexp);
ret = FAIL;
}
}
}
- else if (ZBX_CONDITION_OPERATOR_NOT_EXIST == condition->op)
- {
- ret = SUCCEED;
- }
- else if (ZBX_CONDITION_OPERATOR_EXIST != condition->op)
+ else
{
- *info = zbx_strdcatf(*info,
- "Cannot accurately apply filter: no value received for macro \"%s\".\n",
- condition->macro);
+ switch (condition->op)
+ {
+ case ZBX_CONDITION_OPERATOR_NOT_EXIST:
+ *result = 1;
+ break;
+ case ZBX_CONDITION_OPERATOR_EXIST:
+ *result = 0;
+ break;
+ default:
+ *info = zbx_strdcatf(*info, "Cannot accurately apply filter: no value received for "
+ "macro \"%s\".\n", condition->macro);
+ ret = FAIL;
+ }
}
zbx_free(value);
@@ -259,120 +273,104 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx
return ret;
}
-/******************************************************************************
- * *
- * Purpose: check if the lld data passes filter evaluation by and/or rule *
- * *
- * Parameters: filter - [IN] the lld filter *
- * jp_row - [IN] the lld data row *
- * lld_macro_paths - [IN] use json path to extract from jp_row *
- * info - [OUT] the warning description *
- * *
- * Return value: SUCCEED - the lld data passed filter evaluation *
- * FAIL - otherwise *
- * *
- ******************************************************************************/
-static int filter_evaluate_and_or(const lld_filter_t *filter, const struct zbx_json_parse *jp_row,
+/****************************************************************************************
+ * *
+ * Purpose: check if the lld data passes filter evaluation by and/or/andor rules *
+ * *
+ * Parameters: filter - [IN] the lld filter *
+ * jp_row - [IN] the lld data row *
+ * lld_macro_paths - [IN] use json path to extract from jp_row *
+ * info - [OUT] the warning description *
+ * *
+ * Return value: SUCCEED - the lld data passed filter evaluation *
+ * FAIL - otherwise *
+ * *
+ ****************************************************************************************/
+static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct zbx_json_parse *jp_row,
const zbx_vector_ptr_t *lld_macro_paths, char **info)
{
- int i, ret = SUCCEED;
- char *lastmacro = NULL;
+ int i, ret = SUCCEED, error_num = 0, res;
+ double result;
+ char *lastmacro = NULL;
+ lld_condition_t *condition;
+ char *ops[] = {NULL, "and", "or"}, error[256], *expression = NULL, *errmsg = NULL;
+ size_t expression_alloc = 0, expression_offset = 0;
+ zbx_vector_ptr_t errmsgs;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+ zbx_vector_ptr_create(&errmsgs);
+
for (i = 0; i < filter->conditions.values_num; i++)
{
- int rc;
- const lld_condition_t *condition = (lld_condition_t *)filter->conditions.values[i];
+ condition = (lld_condition_t *)filter->conditions.values[i];
- rc = filter_condition_match(jp_row, lld_macro_paths, condition, info);
- /* check if a new condition group has started */
- if (NULL == lastmacro || 0 != strcmp(lastmacro, condition->macro))
+ switch (filter->evaltype)
{
- /* if any of condition groups are false the evaluation returns false */
- if (FAIL == ret)
+ case ZBX_CONDITION_EVAL_TYPE_AND_OR:
+ if (NULL == lastmacro)
+ {
+ zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, '(');
+ }
+ else if (0 != strcmp(lastmacro, condition->macro))
+ {
+ zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, ") and ");
+ }
+ else
+ zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, " or ");
+
+ lastmacro = condition->macro;
break;
+ case ZBX_CONDITION_EVAL_TYPE_AND:
+ case ZBX_CONDITION_EVAL_TYPE_OR:
+ if (0 != i)
+ {
+ zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' ');
+ zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset,
+ ops[filter->evaltype]);
+ zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' ');
+ }
+ break;
+ default:
+ *info = zbx_strdcatf(*info, "Cannot accurately apply filter: invalid condition "
+ "type \"%d\".\n", filter->evaltype);
+ goto out;
+ }
- ret = rc;
+ if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, condition, &res, &errmsg)))
+ {
+ zbx_snprintf_alloc(&expression, &expression_alloc, &expression_offset, "%d", res);
}
else
{
- if (SUCCEED == rc)
- ret = rc;
+ zbx_snprintf_alloc(&expression, &expression_alloc, &expression_offset, ZBX_UNKNOWN_STR "%d",
+ error_num++);
+ zbx_vector_ptr_append(&errmsgs, errmsg);
+ errmsg = NULL;
}
- lastmacro = condition->macro;
- }
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Purpose: check if the lld data passes filter evaluation by and rule *
- * *
- * Parameters: filter - [IN] the lld filter *
- * jp_row - [IN] the lld data row *
- * lld_macro_paths - [IN] use json path to extract from jp_row *
- * info - [OUT] the warning description *
- * *
- * Return value: SUCCEED - the lld data passed filter evaluation *
- * FAIL - otherwise *
- * *
- ******************************************************************************/
-static int filter_evaluate_and(const lld_filter_t *filter, const struct zbx_json_parse *jp_row,
- const zbx_vector_ptr_t *lld_macro_paths, char **info)
-{
- int i, ret = SUCCEED;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
-
- for (i = 0; i < filter->conditions.values_num; i++)
- {
- /* if any of conditions are false the evaluation returns false */
- if (SUCCEED != (ret = filter_condition_match(jp_row, lld_macro_paths,
- (lld_condition_t *)filter->conditions.values[i], info)))
+ if (filter->conditions.values_num == i + 1)
{
- break;
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == filter->evaltype)
+ zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ')');
+
+ expression_offset++;
}
}
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Purpose: check if the lld data passes filter evaluation by or rule *
- * *
- * Parameters: filter - [IN] the lld filter *
- * jp_row - [IN] the lld data row *
- * lld_macro_paths - [IN] use json path to extract from jp_row *
- * info - [OUT] the warning description *
- * *
- * Return value: SUCCEED - the lld data passed filter evaluation *
- * FAIL - otherwise *
- * *
- ******************************************************************************/
-static int filter_evaluate_or(const lld_filter_t *filter, const struct zbx_json_parse *jp_row,
- const zbx_vector_ptr_t *lld_macro_paths, char **info)
-{
- int i, ret = SUCCEED;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
-
- for (i = 0; i < filter->conditions.values_num; i++)
+ if (SUCCEED == zbx_evaluate(&result, expression, error, sizeof(error), &errmsgs))
{
- /* if any of conditions are true the evaluation returns true */
- if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths,
- (lld_condition_t *)filter->conditions.values[i], info)))
- {
- break;
- }
+ ret = (SUCCEED != zbx_double_compare(result, 0) ? SUCCEED : FAIL);
+ }
+ else
+ {
+ *info = zbx_strdcat(*info, error);
+ ret = FAIL;
}
+out:
+ zbx_free(expression);
+ zbx_vector_ptr_clear_ext(&errmsgs, zbx_ptr_free);
+ zbx_vector_ptr_destroy(&errmsgs);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
@@ -400,37 +398,66 @@ static int filter_evaluate_or(const lld_filter_t *filter, const struct zbx_json_
static int filter_evaluate_expression(const lld_filter_t *filter, const struct zbx_json_parse *jp_row,
const zbx_vector_ptr_t *lld_macro_paths, char **info)
{
- int i, ret = FAIL, id_len;
- char *expression, id[ZBX_MAX_UINT64_LEN + 2], *p, error[256];
- double result;
+ int i, ret = FAIL, res, error_num = 0;
+ char *expression = NULL, id[ZBX_MAX_UINT64_LEN + 2], *p, error[256], value[16],
+ *errmsg = NULL;
+ double result;
+ zbx_vector_ptr_t errmsgs;
+ size_t expression_alloc = 0, expression_offset = 0, id_len, value_len;
zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:%s", __func__, filter->expression);
- expression = zbx_strdup(NULL, filter->expression);
+ zbx_strcpy_alloc(&expression, &expression_alloc, &expression_offset, filter->expression);
+
+ /* include trailing zero */
+ expression_offset++;
+
+ zbx_vector_ptr_create(&errmsgs);
for (i = 0; i < filter->conditions.values_num; i++)
{
const lld_condition_t *condition = (lld_condition_t *)filter->conditions.values[i];
- ret = filter_condition_match(jp_row, lld_macro_paths, condition, info);
+ if (SUCCEED == (ret = filter_condition_match(jp_row, lld_macro_paths, condition, &res, &errmsg)))
+ {
+ zbx_snprintf(value, sizeof(value), "%d", res);
+ }
+ else
+ {
+ zbx_snprintf(value, sizeof(value), ZBX_UNKNOWN_STR "%d", error_num++);
+ zbx_vector_ptr_append(&errmsgs, errmsg);
+ errmsg = NULL;
+ }
zbx_snprintf(id, sizeof(id), "{" ZBX_FS_UI64 "}", condition->id);
+ value_len = strlen(value);
id_len = strlen(id);
- p = expression;
- while (NULL != (p = strstr(p, id)))
+ for (p = strstr(expression, id); NULL != p; p = strstr(p, id))
{
- *p = (SUCCEED == ret ? '1' : '0');
- memset(p + 1, ' ', id_len - 1);
- p += id_len;
+ size_t id_pos = p - expression;
+
+ zbx_replace_mem_dyn(&expression, &expression_alloc, &expression_offset, id_pos, id_len,
+ value, value_len);
+
+ p = expression + id_pos + value_len;
}
}
- if (SUCCEED == zbx_evaluate(&result, expression, error, sizeof(error), NULL))
+ if (SUCCEED == zbx_evaluate(&result, expression, error, sizeof(error), &errmsgs))
+ {
ret = (SUCCEED != zbx_double_compare(result, 0) ? SUCCEED : FAIL);
+ }
+ else
+ {
+ *info = zbx_strdcat(*info, error);
+ ret = FAIL;
+ }
zbx_free(expression);
+ zbx_vector_ptr_clear_ext(&errmsgs, zbx_ptr_free);
+ zbx_vector_ptr_destroy(&errmsgs);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
@@ -453,15 +480,16 @@ static int filter_evaluate_expression(const lld_filter_t *filter, const struct z
static int filter_evaluate(const lld_filter_t *filter, const struct zbx_json_parse *jp_row,
const zbx_vector_ptr_t *lld_macro_paths, char **info)
{
+ if (0 == filter->conditions.values_num)
+ return SUCCEED;
+
switch (filter->evaltype)
{
- case ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR:
- return filter_evaluate_and_or(filter, jp_row, lld_macro_paths, info);
- case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
- return filter_evaluate_and(filter, jp_row, lld_macro_paths, info);
- case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
- return filter_evaluate_or(filter, jp_row, lld_macro_paths, info);
- case ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION:
+ case ZBX_CONDITION_EVAL_TYPE_AND_OR:
+ case ZBX_CONDITION_EVAL_TYPE_AND:
+ case ZBX_CONDITION_EVAL_TYPE_OR:
+ return filter_evaluate_and_or_andor(filter, jp_row, lld_macro_paths, info);
+ case ZBX_CONDITION_EVAL_TYPE_EXPRESSION:
return filter_evaluate_expression(filter, jp_row, lld_macro_paths, info);
}
@@ -512,7 +540,7 @@ static int lld_override_conditions_load(zbx_vector_ptr_t *overrides, const zbx_v
{
override = (lld_override_t *)overrides->values[i];
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == override->filter.evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == override->filter.evaltype)
zbx_vector_ptr_sort(&override->filter.conditions, lld_condition_compare_by_macro);
}
diff --git a/src/zabbix_server/service/service_manager.c b/src/zabbix_server/service/service_manager.c
index 3b578168c86..103dd1e40ee 100644
--- a/src/zabbix_server/service/service_manager.c
+++ b/src/zabbix_server/service/service_manager.c
@@ -966,14 +966,14 @@ static void update_action_formula(zbx_service_action_t *action)
zabbix_log(LOG_LEVEL_DEBUG, "In %s() actionid:" ZBX_FS_UI64, __func__, action->actionid);
- if (0 == action->conditions.values_num || ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (0 == action->conditions.values_num || ZBX_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
goto out;
for (i = 0; i < action->conditions.values_num; i++)
{
condition = (zbx_service_action_condition_t *)action->conditions.values[i];
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
{
if (last_type != condition->conditiontype)
{
@@ -1000,7 +1000,7 @@ static void update_action_formula(zbx_service_action_t *action)
last_type = condition->conditiontype;
}
- if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_chrcpy_alloc(&formula, &formula_alloc, &formula_offset, ')');
zbx_free(action->formula);