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:
authorAndrejs Sitals <andrejs.sitals@zabbix.com>2020-09-15 12:54:07 +0300
committerAndrejs Sitals <andrejs.sitals@zabbix.com>2020-09-15 12:54:07 +0300
commit97a4c01138baf783c6d65df300a0f6dc4cad4cef (patch)
tree1bcc623aec21eb9b1f746ab0f342df13d8598848
parentd44b6c793f2f7dad713b8a66f4af7d63a2fb00b8 (diff)
........S. [ZBXNEXT-6186] added support of expression macros in event names in trigger configuration (asitals)
-rw-r--r--include/common.h2
-rw-r--r--include/zbxserver.h1
-rw-r--r--src/libs/zbxcommon/str.c64
-rw-r--r--src/libs/zbxserver/expression.c74
-rw-r--r--src/zabbix_server/events.c2
5 files changed, 138 insertions, 5 deletions
diff --git a/include/common.h b/include/common.h
index e71955870e7..458e9ecba8d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -1409,6 +1409,7 @@ int zbx_strcmp_natural(const char *s1, const char *s2);
#define ZBX_TOKEN_SIMPLE_MACRO 0x00020
#define ZBX_TOKEN_REFERENCE 0x00040
#define ZBX_TOKEN_LLD_FUNC_MACRO 0x00080
+#define ZBX_TOKEN_EXPRESSION_MACRO 0x00100
/* additional token flags */
#define ZBX_TOKEN_TRIGGER 0x004000
@@ -1489,6 +1490,7 @@ typedef union
zbx_token_macro_t objectid;
zbx_token_macro_t macro;
zbx_token_macro_t lld_macro;
+ zbx_token_macro_t expression_macro;
zbx_token_user_macro_t user_macro;
zbx_token_func_macro_t func_macro;
zbx_token_func_macro_t lld_func_macro;
diff --git a/include/zbxserver.h b/include/zbxserver.h
index d6de7772675..b144f357c33 100644
--- a/include/zbxserver.h
+++ b/include/zbxserver.h
@@ -48,6 +48,7 @@
#define MACRO_TYPE_HTTP_XML 0x00400000
#define MACRO_TYPE_ALLOWED_HOSTS 0x00800000
#define MACRO_TYPE_ITEM_TAG 0x01000000
+#define MACRO_TYPE_EVENT_NAME 0x02000000 /* event name in trigger configuration */
#define MACRO_EXPAND_NO 0
#define MACRO_EXPAND_YES 1
diff --git a/src/libs/zbxcommon/str.c b/src/libs/zbxcommon/str.c
index 17d50705d76..3514db13d17 100644
--- a/src/libs/zbxcommon/str.c
+++ b/src/libs/zbxcommon/str.c
@@ -3627,6 +3627,66 @@ static int zbx_token_parse_lld_macro(const char *expression, const char *macro,
/******************************************************************************
* *
+ * Function: zbx_token_parse_expression_macro *
+ * *
+ * Purpose: parses expression macro token *
+ * *
+ * Parameters: expression - [IN] the expression *
+ * macro - [IN] the beginning of the token *
+ * token - [OUT] the token data *
+ * *
+ * Return value: SUCCEED - the expression macro was parsed successfully *
+ * FAIL - macro does not point at valid expression macro *
+ * *
+ * Comments: If the macro points at valid expression macro in the expression *
+ * then the generic token fields are set and the *
+ * token->data.expression_macro structure is filled with expression *
+ * macro specific data. *
+ * Contents of macro are not validated because expression macro may *
+ * contain user macro contexts and item keys with string arguments. *
+ * *
+ ******************************************************************************/
+static int zbx_token_parse_expression_macro(const char *expression, const char *macro, zbx_token_t *token)
+{
+ const char *ptr;
+ size_t level;
+ size_t offset;
+ zbx_token_macro_t *data;
+
+ /* find the end of expression macro */
+ for (ptr = macro + 2, level = 1; '}' != *ptr || 1 != level; ptr++)
+ {
+ if ('\0' == *ptr)
+ return FAIL;
+
+ if ('{' == *ptr)
+ level++;
+
+ if ('}' == *ptr)
+ level--;
+ }
+
+ /* empty macro */
+ if (ptr == macro + 2)
+ return FAIL;
+
+ offset = macro - expression;
+
+ /* initialize token */
+ token->type = ZBX_TOKEN_EXPRESSION_MACRO;
+ token->loc.l = offset;
+ token->loc.r = offset + (ptr - macro);
+
+ /* initialize token data */
+ data = &token->data.expression_macro;
+ data->name.l = offset + 2;
+ data->name.r = token->loc.r - 1;
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
* Function: zbx_token_parse_objectid *
* *
* Purpose: parses object id token *
@@ -4223,7 +4283,9 @@ int zbx_token_find(const char *expression, int pos, zbx_token_t *token, zbx_toke
case '#':
ret = zbx_token_parse_lld_macro(expression, ptr, token);
break;
-
+ case '?':
+ ret = zbx_token_parse_expression_macro(expression, ptr, token);
+ break;
case '{':
ret = zbx_token_parse_nested_macro(expression, ptr, token);
break;
diff --git a/src/libs/zbxserver/expression.c b/src/libs/zbxserver/expression.c
index 0f295bb5ee5..57fce5fbf9f 100644
--- a/src/libs/zbxserver/expression.c
+++ b/src/libs/zbxserver/expression.c
@@ -2525,6 +2525,61 @@ static void get_event_value(const char *macro, const DB_EVENT *event, char **rep
/******************************************************************************
* *
+ * Function: get_expression_macro_result *
+ * *
+ * Purpose: calculate result of expression macro *
+ * *
+ * Return value: upon successful completion return SUCCEED *
+ * otherwise FAIL *
+ * *
+ ******************************************************************************/
+static int get_expression_macro_result(const DB_EVENT *event, const DB_EVENT *r_event, DB_ALERT *alert,
+ const DB_ACKNOWLEDGE *ack, char **expression, char **replace_to, char *error, int maxerrlen)
+{
+ int ret;
+ double expression_result;
+ int unknown_idx;
+ zbx_vector_ptr_t unknown_msgs; /* pointers to messages about origins of 'unknown' values */
+ char eval_errors[1024] = { 0 };
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:'%s'", __func__, *expression);
+
+ substitute_simple_macros_impl(NULL, event, r_event, NULL, NULL, NULL, NULL, alert, ack, NULL, expression,
+ MACRO_TYPE_MESSAGE_NORMAL, error, maxerrlen);
+
+ zbx_vector_ptr_create(&unknown_msgs);
+
+ if (SUCCEED != evaluate(&expression_result, *expression, eval_errors, sizeof(eval_errors), &unknown_msgs))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() %s", __func__, eval_errors);
+
+ for (unknown_idx = 0; unknown_idx < unknown_msgs.values_num; unknown_idx++)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() %s", __func__, (char *)(unknown_msgs.values[unknown_idx]));
+ }
+
+ ret = FAIL;
+ }
+ else
+ {
+ size_t alloc_len;
+ size_t offset;
+
+ zbx_snprintf_alloc(replace_to, &alloc_len, &offset, "%f", expression_result);
+
+ ret = SUCCEED;
+ }
+
+ zbx_vector_ptr_clear_ext(&unknown_msgs, zbx_ptr_free);
+ zbx_vector_ptr_destroy(&unknown_msgs);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
* Function: get_history_log_value *
* *
* Purpose: retrieve a particular attribute of a log value *
@@ -2937,7 +2992,7 @@ static int substitute_simple_macros_impl(zbx_uint64_t *actionid, const DB_EVENT
zabbix_log(LOG_LEVEL_DEBUG, "In %s() data:'%s'", __func__, *data);
- if (0 != (macro_type & MACRO_TYPE_TRIGGER_DESCRIPTION))
+ if (0 != (macro_type & (MACRO_TYPE_TRIGGER_DESCRIPTION | MACRO_TYPE_EVENT_NAME)))
token_search = ZBX_TOKEN_SEARCH_REFERENCES;
else
token_search = ZBX_TOKEN_SEARCH_BASIC;
@@ -2963,7 +3018,7 @@ static int substitute_simple_macros_impl(zbx_uint64_t *actionid, const DB_EVENT
case ZBX_TOKEN_OBJECTID:
case ZBX_TOKEN_LLD_MACRO:
case ZBX_TOKEN_LLD_FUNC_MACRO:
- /* neither lld or {123123} macros are processed by this function, skip them */
+ /* neither lld nor {123123} macros are processed by this function, skip them */
pos = token.loc.r + 1;
continue;
case ZBX_TOKEN_MACRO:
@@ -3011,6 +3066,7 @@ static int substitute_simple_macros_impl(zbx_uint64_t *actionid, const DB_EVENT
m = NULL;
break;
case ZBX_TOKEN_REFERENCE:
+ case ZBX_TOKEN_EXPRESSION_MACRO:
/* These macros (and probably all other in the future) must be resolved using only */
/* information stored in token.data union. For now, force crash if they rely on m. */
m = NULL;
@@ -4059,7 +4115,8 @@ static int substitute_simple_macros_impl(zbx_uint64_t *actionid, const DB_EVENT
}
}
}
- else if (0 != (macro_type & (MACRO_TYPE_TRIGGER_DESCRIPTION | MACRO_TYPE_TRIGGER_COMMENTS)))
+ else if (0 != (macro_type & (MACRO_TYPE_TRIGGER_DESCRIPTION | MACRO_TYPE_TRIGGER_COMMENTS |
+ MACRO_TYPE_EVENT_NAME)))
{
if (EVENT_OBJECT_TRIGGER == event->object)
{
@@ -4083,6 +4140,17 @@ static int substitute_simple_macros_impl(zbx_uint64_t *actionid, const DB_EVENT
get_trigger_expression_constant(expression, &token.data.reference, &replace_to);
}
+ else if (ZBX_TOKEN_EXPRESSION_MACRO == token.type &&
+ 0 != (macro_type & MACRO_TYPE_EVENT_NAME))
+ {
+ c = (*data)[token.loc.r];
+ (*data)[token.loc.r] = '\0';
+
+ expression = zbx_strdup(expression, *data + token.loc.l + 2);
+
+ ret = get_expression_macro_result(event, r_event, alert, ack, &expression,
+ &replace_to, error, maxerrlen);
+ }
else if (0 == strcmp(m, MVAR_HOST_HOST) || 0 == strcmp(m, MVAR_HOSTNAME))
{
ret = DBget_trigger_value(event->trigger.expression, &replace_to, N_functionid,
diff --git a/src/zabbix_server/events.c b/src/zabbix_server/events.c
index 2566209b150..a52653b2ca8 100644
--- a/src/zabbix_server/events.c
+++ b/src/zabbix_server/events.c
@@ -241,7 +241,7 @@ DB_EVENT *zbx_add_event(unsigned char source, unsigned char object, zbx_uint64_t
&event->trigger.correlation_tag, MACRO_TYPE_TRIGGER_TAG, NULL, 0);
substitute_simple_macros(NULL, event, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &event->name, MACRO_TYPE_TRIGGER_DESCRIPTION, NULL, 0);
+ &event->name, MACRO_TYPE_EVENT_NAME, NULL, 0);
zbx_vector_ptr_create(&event->tags);