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:
Diffstat (limited to 'src/libs/zbxserver/expression_eval.c')
-rw-r--r--src/libs/zbxserver/expression_eval.c219
1 files changed, 218 insertions, 1 deletions
diff --git a/src/libs/zbxserver/expression_eval.c b/src/libs/zbxserver/expression_eval.c
index c83c2f76c6f..67e8dcf8114 100644
--- a/src/libs/zbxserver/expression_eval.c
+++ b/src/libs/zbxserver/expression_eval.c
@@ -1068,6 +1068,8 @@ out:
#define ZBX_VALUE_FUNC_LAST 6
#define ZBX_ITEM_FUNC_EXISTS 7
#define ZBX_ITEM_FUNC_ITEMCOUNT 8
+#define ZBX_ITEM_FUNC_BPERCENTL 9
+#define ZBX_MIXVALUE_FUNC_BRATE 10
#define MATCH_STRING(x, name, len) ZBX_CONST_STRLEN(x) == len && 0 == memcmp(name, x, len)
@@ -1098,6 +1100,12 @@ static int get_function_by_name(const char *name, size_t len)
if (MATCH_STRING("item_count", name, len))
return ZBX_ITEM_FUNC_ITEMCOUNT;
+ if (MATCH_STRING("bucket_percentile", name, len))
+ return ZBX_ITEM_FUNC_BPERCENTL;
+
+ if (MATCH_STRING("bucket_rate_foreach", name, len))
+ return ZBX_MIXVALUE_FUNC_BRATE;
+
return ZBX_VALUE_FUNC_UNKNOWN;
}
@@ -1317,6 +1325,22 @@ static DC_ITEM *get_dcitem(zbx_vector_ptr_t *dcitem_refs, zbx_uint64_t itemid)
return dcitem_refs->values[index];
}
+/******************************************************************************
+ * *
+ * Function: expression_eval_exists *
+ * *
+ * Purpose: evaluate functions 'exists_foreach' and 'item_count' *
+ * for multiple items *
+ * *
+ * Parameters: eval - [IN] the evaluation data *
+ * query - [IN] the calculated item query *
+ * item_func - [IN] the function id *
+ * value - [OUT] the function return value *
+ * *
+ * Return value: SUCCEED - the function was executed successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
static void expression_eval_exists(zbx_expression_eval_t *eval, zbx_expression_query_t *query, int item_func,
zbx_variant_t *value)
{
@@ -1361,6 +1385,195 @@ static void expression_eval_exists(zbx_expression_eval_t *eval, zbx_expression_q
/******************************************************************************
* *
+ * Function: expression_eval_bucket_rate *
+ * *
+ * Purpose: evaluate functions 'bucket_rate_foreach' for 'histogram_quantile' *
+ * and evaluate functions 'bucket_percentile' *
+ * *
+ * Parameters: eval - [IN] the evaluation data *
+ * query - [IN] the calculated item query *
+ * args_num - [IN] the number of function arguments *
+ * args - [IN] an array of the function arguments. *
+ * data - [IN] the caller data used for function evaluation *
+ * ts - [IN] the function execution time *
+ * item_func - [IN] the function id *
+ * value - [OUT] the function return value *
+ * error - [OUT] the error message if function failed *
+ * *
+ * Return value: SUCCEED - the function was executed successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int expression_eval_bucket_rate(zbx_expression_eval_t *eval, zbx_expression_query_t *query,
+ int args_num, const zbx_variant_t *args, const zbx_timespec_t *ts, int item_func, zbx_variant_t *value,
+ char **error)
+{
+ zbx_expression_query_many_t *data;
+ int i, pos, ret = FAIL;
+ zbx_vector_dbl_t *results = NULL;
+ double percentage, result;
+ char *param = NULL, *backet = NULL;
+ const char *log_fn = (ZBX_ITEM_FUNC_BPERCENTL == item_func ?
+ "bucket_percentile" : "bucket_rate_foreach");
+
+ if (1 > args_num || 2 < args_num || (ZBX_ITEM_FUNC_BPERCENTL == item_func && 2 != args_num))
+ {
+ *error = zbx_strdup(NULL, "invalid number of function parameters");
+ goto err;
+ }
+
+ if (ZBX_VARIANT_STR == args[0].type)
+ {
+ param = zbx_strdup(NULL, args[0].data.str);
+ }
+ else
+ {
+ zbx_variant_t arg;
+
+ zbx_variant_copy(&arg, &args[0]);
+
+ if (SUCCEED != zbx_variant_convert(&arg, ZBX_VARIANT_STR))
+ {
+ zbx_variant_clear(&arg);
+ *error = zbx_strdup(NULL, "invalid second parameter");
+ goto err;
+ }
+
+ param = zbx_strdup(NULL, arg.data.str);
+ zbx_variant_clear(&arg);
+ }
+
+ if (ZBX_ITEM_FUNC_BPERCENTL == item_func)
+ {
+ if (ZBX_VARIANT_DBL == args[1].type)
+ {
+ percentage = args[1].data.dbl;
+ }
+ else
+ {
+ zbx_variant_t val_copy;
+
+ zbx_variant_copy(&val_copy, &args[1]);
+
+ if (SUCCEED != zbx_variant_convert(&val_copy, ZBX_VARIANT_DBL))
+ {
+ zbx_variant_clear(&val_copy);
+ *error = zbx_strdup(NULL, "invalid third parameter");
+ goto err;
+ }
+
+ percentage = val_copy.data.dbl;
+ }
+
+ if (100 < percentage || 0 > percentage)
+ {
+ *error = zbx_strdup(NULL, "invalid value of percentile");
+ goto err;
+ }
+
+ pos = 1;
+ }
+ else if (2 == args_num)
+ {
+ if (ZBX_VARIANT_STR == args[1].type)
+ {
+ if (SUCCEED != is_ushort(args[1].data.str, &pos) || 0 >= pos)
+ {
+ *error = zbx_strdup(NULL, "invalid third parameter");
+ goto err;
+ }
+ }
+ else if (ZBX_VARIANT_UI64 == args[1].type)
+ {
+ if (0 >= (pos = (int)args[1].data.ui64))
+ {
+ *error = zbx_strdup(NULL, "invalid third parameter");
+ goto err;
+ }
+ }
+ else
+ {
+ *error = zbx_strdup(NULL, "invalid third parameter");
+ goto err;
+ }
+ }
+ else
+ {
+ pos = 1;
+ }
+
+ data = (zbx_expression_query_many_t *)query->data;
+ results = (zbx_vector_dbl_t *)zbx_malloc(NULL, sizeof(zbx_vector_dbl_t));
+ zbx_vector_dbl_create(results);
+
+ for (i = 0; i < data->itemids.values_num; i++)
+ {
+ DC_ITEM *dcitem;
+ zbx_variant_t rate;
+ double le;
+ const char *s;
+
+
+ if (NULL == (dcitem = get_dcitem(&eval->dcitem_refs, data->itemids.values[i])))
+ continue;
+
+ if (ITEM_STATUS_ACTIVE != dcitem->status)
+ continue;
+
+ if (HOST_STATUS_MONITORED != dcitem->host.status)
+ continue;
+
+ if (ITEM_VALUE_TYPE_FLOAT != dcitem->value_type && ITEM_VALUE_TYPE_UINT64 != dcitem->value_type)
+ continue;
+
+ zbx_free(backet);
+
+ for (s = dcitem->key_orig; SUCCEED == is_key_char((unsigned char)*s); s++)
+ ;
+
+ if (dcitem->key_orig == s || NULL == (backet = get_param_dyn(s, pos, NULL))) /* the key is empty */
+ continue;
+
+ zbx_strupper(backet);
+
+ if (0 == strcmp(backet, "+INF") || 0 == strcmp(backet, "INF"))
+ le = ZBX_INFINITY;
+ else if (SUCCEED != is_double(backet, &le))
+ continue;
+
+ if (SUCCEED != (ret = zbx_evaluate_RATE(&rate, dcitem, param, ts, error)))
+ goto err;
+
+ zbx_vector_dbl_append(results, le);
+ zbx_vector_dbl_append(results, rate.data.dbl);
+ }
+
+ if (ZBX_MIXVALUE_FUNC_BRATE == item_func)
+ {
+ zbx_variant_set_dbl_vector(value, results);
+ results = NULL;
+ ret = SUCCEED;
+ }
+ else if (ZBX_ITEM_FUNC_BPERCENTL == item_func && SUCCEED == (
+ ret = zbx_eval_calc_histogram_quantile(percentage / 100, results, log_fn, &result, error)))
+ {
+ zbx_variant_set_dbl(value, result);
+ }
+err:
+ zbx_free(param);
+ zbx_free(backet);
+
+ if (NULL != results)
+ {
+ zbx_vector_dbl_destroy(results);
+ zbx_free(results);
+ }
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
* Function: expression_eval_many *
* *
* Purpose: evaluate historical function for multiple items (aggregate checks)*
@@ -1453,6 +1666,10 @@ static int expression_eval_many(zbx_expression_eval_t *eval, zbx_expression_quer
count = 0;
break;
+ case ZBX_ITEM_FUNC_BPERCENTL:
+ case ZBX_MIXVALUE_FUNC_BRATE:
+ ret = expression_eval_bucket_rate(eval, query, args_num, args, ts, item_func, value, error);
+ goto out;
default:
*error = zbx_strdup(NULL, "unsupported function");
goto out;
@@ -1522,7 +1739,7 @@ static int expression_eval_history(const char *name, size_t len, int args_num, c
void *data, const zbx_timespec_t *ts, zbx_variant_t *value, char **error)
{
int ret = FAIL;
- zbx_expression_eval_t *eval;
+ zbx_expression_eval_t *eval;
zbx_expression_query_t *query;
char *errmsg = NULL;