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:
authorAndris Zeila <andris.zeila@zabbix.com>2018-10-22 15:59:38 +0300
committerAndris Zeila <andris.zeila@zabbix.com>2018-10-22 15:59:38 +0300
commit3b3bcb51117fa60afe901de4a20a373e4e8bde13 (patch)
tree2bb6dc07e01ece00f3a8b602c066771333984f52
parent755091f798cc252aa5ea437b6d8ad7c444ffba89 (diff)
........S. [ZBXNEXT-4724] reworked preprocessing step history storage to support multiple history based steps
-rw-r--r--include/dbcache.h9
-rw-r--r--src/libs/zbxdbcache/dbconfig.h2
-rw-r--r--src/zabbix_server/preprocessor/Makefile.am3
-rw-r--r--src/zabbix_server/preprocessor/item_preproc.c86
-rw-r--r--src/zabbix_server/preprocessor/item_preproc.h2
-rw-r--r--src/zabbix_server/preprocessor/preproc_history.c70
-rw-r--r--src/zabbix_server/preprocessor/preproc_history.h50
-rw-r--r--src/zabbix_server/preprocessor/preproc_manager.c79
-rw-r--r--src/zabbix_server/preprocessor/preproc_worker.c51
-rw-r--r--src/zabbix_server/preprocessor/preprocessing.c187
-rw-r--r--src/zabbix_server/preprocessor/preprocessing.h10
-rw-r--r--tests/zabbix_server/preprocessor/zbx_item_preproc.c44
-rw-r--r--tests/zabbix_server/preprocessor/zbx_item_preproc.yaml30
13 files changed, 424 insertions, 199 deletions
diff --git a/include/dbcache.h b/include/dbcache.h
index 5a4af26d77c..3343ac5759f 100644
--- a/include/dbcache.h
+++ b/include/dbcache.h
@@ -467,15 +467,6 @@ ZBX_DC_TREND;
typedef struct
{
- zbx_uint64_t itemid;
- zbx_timespec_t timestamp;
- zbx_variant_t value;
- unsigned char value_type;
-}
-zbx_item_history_value_t;
-
-typedef struct
-{
zbx_uint64_t itemid;
history_value_t value;
zbx_uint64_t lastlogsize;
diff --git a/src/libs/zbxdbcache/dbconfig.h b/src/libs/zbxdbcache/dbconfig.h
index 4b1532a36dc..eab59441cd7 100644
--- a/src/libs/zbxdbcache/dbconfig.h
+++ b/src/libs/zbxdbcache/dbconfig.h
@@ -261,8 +261,6 @@ typedef struct
}
ZBX_DC_HTTPITEM;
-typedef zbx_item_history_value_t ZBX_DC_DELTAITEM;
-
#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
typedef struct
{
diff --git a/src/zabbix_server/preprocessor/Makefile.am b/src/zabbix_server/preprocessor/Makefile.am
index c2236b8e72b..c8ba4542bf7 100644
--- a/src/zabbix_server/preprocessor/Makefile.am
+++ b/src/zabbix_server/preprocessor/Makefile.am
@@ -8,7 +8,8 @@ libpreprocessor_a_SOURCES = \
preproc_manager.c preproc_manager.h \
item_preproc.c \
item_preproc.h \
- preprocessing.c preprocessing.h
+ preprocessing.c preprocessing.h \
+ preproc_history.c preproc_history.h
libpreprocessor_a_CFLAGS = \
@LIBXML2_CFLAGS@
diff --git a/src/zabbix_server/preprocessor/item_preproc.c b/src/zabbix_server/preprocessor/item_preproc.c
index b7a8c7f217f..1873161e694 100644
--- a/src/zabbix_server/preprocessor/item_preproc.c
+++ b/src/zabbix_server/preprocessor/item_preproc.c
@@ -214,33 +214,34 @@ static int item_preproc_multiplier(unsigned char value_type, zbx_variant_t *valu
* *
* Purpose: execute delta type preprocessing operation *
* *
- * Parameters: value - [IN/OUT] the value to process *
- * ts - [IN] the value timestamp *
- * op_type - [IN] the operation type *
- * hvalue - [IN] the item historical data *
+ * Parameters: value - [IN/OUT] the value to process *
+ * ts - [IN] the value timestamp *
+ * op_type - [IN] the operation type *
+ * history_value - [IN] the item historical data *
+ * history_ts - [IN] the historical data timestamp *
* *
* Return value: SUCCEED - the value was calculated successfully *
* FAIL - otherwise *
* *
******************************************************************************/
static int item_preproc_delta_float(zbx_variant_t *value, const zbx_timespec_t *ts, unsigned char op_type,
- zbx_item_history_value_t *hvalue)
+ const zbx_variant_t *history_value, const zbx_timespec_t *history_ts)
{
- if (0 == hvalue->timestamp.sec || hvalue->value.data.dbl > value->data.dbl)
+ if (0 == history_ts->sec || history_value->data.dbl > value->data.dbl)
return FAIL;
switch (op_type)
{
case ZBX_PREPROC_DELTA_SPEED:
- if (0 <= zbx_timespec_compare(&hvalue->timestamp, ts))
+ if (0 <= zbx_timespec_compare(history_ts, ts))
return FAIL;
- value->data.dbl = (value->data.dbl - hvalue->value.data.dbl) /
- ((ts->sec - hvalue->timestamp.sec) +
- (double)(ts->ns - hvalue->timestamp.ns) / 1000000000);
+ value->data.dbl = (value->data.dbl - history_value->data.dbl) /
+ ((ts->sec - history_ts->sec) +
+ (double)(ts->ns - history_ts->ns) / 1000000000);
break;
case ZBX_PREPROC_DELTA_VALUE:
- value->data.dbl = value->data.dbl - hvalue->value.data.dbl;
+ value->data.dbl = value->data.dbl - history_value->data.dbl;
break;
}
@@ -253,33 +254,34 @@ static int item_preproc_delta_float(zbx_variant_t *value, const zbx_timespec_t *
* *
* Purpose: execute delta type preprocessing operation *
* *
- * Parameters: value - [IN/OUT] the value to process *
- * ts - [IN] the value timestamp *
- * op_type - [IN] the operation type *
- * hvalue - [IN] the item historical data *
+ * Parameters: value - [IN/OUT] the value to process *
+ * ts - [IN] the value timestamp *
+ * op_type - [IN] the operation type *
+ * history_value - [IN] the item historical data *
+ * history_ts - [IN] the historical data timestamp *
* *
* Return value: SUCCEED - the value was calculated successfully *
* FAIL - otherwise *
* *
******************************************************************************/
static int item_preproc_delta_uint64(zbx_variant_t *value, const zbx_timespec_t *ts, unsigned char op_type,
- zbx_item_history_value_t *hvalue)
+ const zbx_variant_t *history_value, const zbx_timespec_t *history_ts)
{
- if (0 == hvalue->timestamp.sec || hvalue->value.data.ui64 > value->data.ui64)
+ if (0 == history_ts->sec || history_value->data.ui64 > value->data.ui64)
return FAIL;
switch (op_type)
{
case ZBX_PREPROC_DELTA_SPEED:
- if (0 <= zbx_timespec_compare(&hvalue->timestamp, ts))
+ if (0 <= zbx_timespec_compare(history_ts, ts))
return FAIL;
- value->data.ui64 = (value->data.ui64 - hvalue->value.data.ui64) /
- ((ts->sec - hvalue->timestamp.sec) +
- (double)(ts->ns - hvalue->timestamp.ns) / 1000000000);
+ value->data.ui64 = (value->data.ui64 - history_value->data.ui64) /
+ ((ts->sec - history_ts->sec) +
+ (double)(ts->ns - history_ts->ns) / 1000000000);
break;
case ZBX_PREPROC_DELTA_VALUE:
- value->data.ui64 = value->data.ui64 - hvalue->value.data.ui64;
+ value->data.ui64 = value->data.ui64 - history_value->data.ui64;
break;
}
@@ -296,8 +298,8 @@ static int item_preproc_delta_uint64(zbx_variant_t *value, const zbx_timespec_t
* value - [IN/OUT] the value to process *
* ts - [IN] the value timestamp *
* op_type - [IN] the operation type *
- * history_value - [IN] historical data of item with delta *
- * preprocessing operation *
+ * history_value - [IN/OUT] the historical (previuous) data *
+ * history_ts - [IN/OUT] the timestamp of the historical data *
* errmsg - [OUT] error message *
* *
* Return value: SUCCEED - the value was calculated successfully *
@@ -305,7 +307,7 @@ static int item_preproc_delta_uint64(zbx_variant_t *value, const zbx_timespec_t
* *
******************************************************************************/
static int item_preproc_delta(unsigned char value_type, zbx_variant_t *value, const zbx_timespec_t *ts,
- unsigned char op_type, zbx_item_history_value_t *history_value, char **errmsg)
+ unsigned char op_type, zbx_variant_t *history_value, zbx_timespec_t *history_ts, char **errmsg)
{
int ret = FAIL;
zbx_variant_t value_num;
@@ -316,21 +318,21 @@ static int item_preproc_delta(unsigned char value_type, zbx_variant_t *value, co
zbx_variant_clear(value);
zbx_variant_set_variant(value, &value_num);
- if (ZBX_VARIANT_DBL == value->type || ZBX_VARIANT_DBL == history_value->value.type)
+ if (ZBX_VARIANT_DBL == value->type || ZBX_VARIANT_DBL == history_value->type)
{
zbx_variant_convert(value, ZBX_VARIANT_DBL);
- zbx_variant_convert(&history_value->value, ZBX_VARIANT_DBL);
- ret = item_preproc_delta_float(value, ts, op_type, history_value);
+ zbx_variant_convert(history_value, ZBX_VARIANT_DBL);
+ ret = item_preproc_delta_float(value, ts, op_type, history_value, history_ts);
}
else
{
zbx_variant_convert(value, ZBX_VARIANT_UI64);
- zbx_variant_convert(&history_value->value, ZBX_VARIANT_UI64);
- ret = item_preproc_delta_uint64(value, ts, op_type, history_value);
+ zbx_variant_convert(history_value, ZBX_VARIANT_UI64);
+ ret = item_preproc_delta_uint64(value, ts, op_type, history_value, history_ts);
}
- history_value->timestamp = *ts;
- zbx_variant_set_variant(&history_value->value, &value_num);
+ *history_ts = *ts;
+ zbx_variant_set_variant(history_value, &value_num);
zbx_variant_clear(&value_num);
if (SUCCEED != ret)
@@ -357,12 +359,15 @@ static int item_preproc_delta(unsigned char value_type, zbx_variant_t *value, co
* *
******************************************************************************/
static int item_preproc_delta_value(unsigned char value_type, zbx_variant_t *value, const zbx_timespec_t *ts,
- zbx_item_history_value_t *history_value, char **errmsg)
+ zbx_variant_t *history_value, zbx_timespec_t *history_ts, char **errmsg)
{
char *err = NULL;
- if (SUCCEED == item_preproc_delta(value_type, value, ts, ZBX_PREPROC_DELTA_VALUE, history_value, &err))
+ if (SUCCEED == item_preproc_delta(value_type, value, ts, ZBX_PREPROC_DELTA_VALUE, history_value, history_ts,
+ &err))
+ {
return SUCCEED;
+ }
*errmsg = zbx_dsprintf(*errmsg, "cannot calculate delta (simple change) for value \"%s\" of type"
" \"%s\": %s", zbx_variant_value_desc(value), zbx_variant_type_desc(value), err);
@@ -390,12 +395,15 @@ static int item_preproc_delta_value(unsigned char value_type, zbx_variant_t *val
* *
******************************************************************************/
static int item_preproc_delta_speed(unsigned char value_type, zbx_variant_t *value, const zbx_timespec_t *ts,
- zbx_item_history_value_t *history_value, char **errmsg)
+ zbx_variant_t *history_value, zbx_timespec_t *history_ts, char **errmsg)
{
char *err = NULL;
- if (SUCCEED == item_preproc_delta(value_type, value, ts, ZBX_PREPROC_DELTA_SPEED, history_value, &err))
+ if (SUCCEED == item_preproc_delta(value_type, value, ts, ZBX_PREPROC_DELTA_SPEED, history_value, history_ts,
+ &err))
+ {
return SUCCEED;
+ }
*errmsg = zbx_dsprintf(*errmsg, "cannot calculate delta (speed per second) for value \"%s\" of type"
" \"%s\": %s", zbx_variant_value_desc(value), zbx_variant_type_desc(value), err);
@@ -1380,7 +1388,7 @@ out:
* *
******************************************************************************/
int zbx_item_preproc(int index, unsigned char value_type, zbx_variant_t *value, const zbx_timespec_t *ts,
- const zbx_preproc_op_t *op, zbx_item_history_value_t *history_value, char **error)
+ const zbx_preproc_op_t *op, zbx_variant_t *history_value, zbx_timespec_t *history_ts, char **error)
{
int ret, error_handler = op->error_handler;
char *errmsg = NULL;
@@ -1412,10 +1420,10 @@ int zbx_item_preproc(int index, unsigned char value_type, zbx_variant_t *value,
ret = item_preproc_hex2dec(value, &errmsg);
break;
case ZBX_PREPROC_DELTA_VALUE:
- ret = item_preproc_delta_value(value_type, value, ts, history_value, &errmsg);
+ ret = item_preproc_delta_value(value_type, value, ts, history_value, history_ts, &errmsg);
break;
case ZBX_PREPROC_DELTA_SPEED:
- ret = item_preproc_delta_speed(value_type, value, ts, history_value, &errmsg);
+ ret = item_preproc_delta_speed(value_type, value, ts, history_value, history_ts, &errmsg);
break;
case ZBX_PREPROC_XPATH:
ret = item_preproc_xpath(value, op->params, &errmsg);
diff --git a/src/zabbix_server/preprocessor/item_preproc.h b/src/zabbix_server/preprocessor/item_preproc.h
index d0ae247f73d..044b856adde 100644
--- a/src/zabbix_server/preprocessor/item_preproc.h
+++ b/src/zabbix_server/preprocessor/item_preproc.h
@@ -23,7 +23,7 @@
#include "dbcache.h"
int zbx_item_preproc(int index, unsigned char value_type, zbx_variant_t *value, const zbx_timespec_t *ts,
- const zbx_preproc_op_t *op, zbx_item_history_value_t *history_value, char **errmsg);
+ const zbx_preproc_op_t *op, zbx_variant_t *history_value, zbx_timespec_t *history_ts, char **error);
int zbx_item_preproc_convert_value_to_numeric(zbx_variant_t *value_num, const zbx_variant_t *value,
unsigned char value_type, char **errmsg);
diff --git a/src/zabbix_server/preprocessor/preproc_history.c b/src/zabbix_server/preprocessor/preproc_history.c
new file mode 100644
index 00000000000..5ee22321764
--- /dev/null
+++ b/src/zabbix_server/preprocessor/preproc_history.c
@@ -0,0 +1,70 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2018 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program 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 General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+#include "common.h"
+#include "log.h"
+
+#include "preproc_history.h"
+
+void zbx_preproc_op_history_free(zbx_preproc_op_history_t *ophistory)
+{
+ zbx_variant_clear(&ophistory->value);
+ zbx_free(ophistory);
+}
+
+const zbx_preproc_op_history_t *zbx_preproc_history_get_value(zbx_vector_ptr_t *history, int type)
+{
+ int i;
+ zbx_preproc_op_history_t *ophistory;
+
+ for (i = 0; i < history->values_num; i++)
+ {
+ ophistory = (zbx_preproc_op_history_t *)history->values[i];
+
+ if (ophistory->type == type)
+ return ophistory;
+ }
+
+ return NULL;
+}
+
+void zbx_preproc_history_set_value(zbx_vector_ptr_t *history, int type, const zbx_variant_t *data,
+ const zbx_timespec_t *ts)
+{
+ int i;
+ zbx_preproc_op_history_t *ophistory;
+
+ for (i = 0; i < history->values_num; i++)
+ {
+ ophistory = (zbx_preproc_op_history_t *)history->values[i];
+
+ if (ophistory->type == type)
+ break;
+ }
+
+ if (i == history->values_num)
+ {
+ ophistory = zbx_malloc(NULL, sizeof(zbx_preproc_op_history_t));
+ ophistory->type = type;
+ zbx_vector_ptr_append(history, ophistory);
+ }
+
+ zbx_variant_set_variant(&ophistory->value, data);
+ ophistory->ts = *ts;
+}
diff --git a/src/zabbix_server/preprocessor/preproc_history.h b/src/zabbix_server/preprocessor/preproc_history.h
new file mode 100644
index 00000000000..3c38121ca09
--- /dev/null
+++ b/src/zabbix_server/preprocessor/preproc_history.h
@@ -0,0 +1,50 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2018 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program 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 General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+#ifndef ZABBIX_PREPROC_HISTORY_H
+#define ZABBIX_PREPROC_HISTORY_H
+
+#include "common.h"
+#include "dbcache.h"
+
+#define ZBX_PREPROC_TYPE_NONE 0
+#define ZBX_PREPROC_TYPE_DELTA 1
+#define ZBX_PREPROC_TYPE_THROTTLE 2
+
+typedef struct
+{
+ unsigned char type;
+ zbx_variant_t value;
+ zbx_timespec_t ts;
+}
+zbx_preproc_op_history_t;
+
+typedef struct
+{
+ zbx_uint64_t itemid;
+ zbx_vector_ptr_t history;
+}
+zbx_preproc_history_t;
+
+void zbx_preproc_op_history_free(zbx_preproc_op_history_t *ophistory);
+const zbx_preproc_op_history_t *zbx_preproc_history_get_value(zbx_vector_ptr_t *history, int type);
+void zbx_preproc_history_set_value(zbx_vector_ptr_t *history, int type, const zbx_variant_t *data,
+ const zbx_timespec_t *ts);
+
+#endif
diff --git a/src/zabbix_server/preprocessor/preproc_manager.c b/src/zabbix_server/preprocessor/preproc_manager.c
index 0ab0727ac29..4f714660eae 100644
--- a/src/zabbix_server/preprocessor/preproc_manager.c
+++ b/src/zabbix_server/preprocessor/preproc_manager.c
@@ -31,6 +31,7 @@
#include "preprocessing.h"
#include "preproc_manager.h"
#include "linked_list.h"
+#include "preproc_history.h"
extern unsigned char process_type, program_type;
extern int server_num, process_num, CONFIG_PREPROCESSOR_FORKS;
@@ -138,32 +139,12 @@ static void request_free_steps(zbx_preprocessing_request_t *request)
******************************************************************************/
static void preprocessor_sync_configuration(zbx_preprocessing_manager_t *manager)
{
- const char *__function_name = "preprocessor_sync_configuration";
- zbx_hashset_iter_t iter;
- zbx_preproc_item_t *item, item_local;
- zbx_item_history_value_t *history_value;
- int ts;
+ const char *__function_name = "preprocessor_sync_configuration";
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ts = manager->cache_ts;
DCconfig_get_preprocessable_items(&manager->item_config, &manager->cache_ts);
- if (ts != manager->cache_ts)
- {
- zbx_hashset_iter_reset(&manager->history_cache, &iter);
- while (NULL != (history_value = (zbx_item_history_value_t *)zbx_hashset_iter_next(&iter)))
- {
- item_local.itemid = history_value->itemid;
- if (NULL == (item = (zbx_preproc_item_t *)zbx_hashset_search(&manager->item_config, &item_local)) ||
- history_value->value_type != item->value_type)
- {
- /* history value is removed if item was removed/disabled or item value type changed */
- zbx_hashset_iter_remove(&iter);
- }
- }
- }
-
zabbix_log(LOG_LEVEL_DEBUG, "End of %s() item config size: %d, history cache size: %d", __function_name,
manager->item_config.num_data, manager->history_cache.num_data);
}
@@ -281,8 +262,11 @@ static zbx_preprocessing_worker_t *preprocessor_get_free_worker(zbx_preprocessin
static zbx_uint32_t preprocessor_create_task(zbx_preprocessing_manager_t *manager,
zbx_preprocessing_request_t *request, unsigned char **task)
{
- zbx_uint32_t size;
- zbx_variant_t value;
+ zbx_uint32_t size;
+ zbx_variant_t value;
+ zbx_preproc_history_t *vault;
+ zbx_vector_ptr_t *phistory;
+
if (ISSET_LOG(request->value.result))
zbx_variant_set_str(&value, request->value.result->log->value);
@@ -297,9 +281,16 @@ static zbx_uint32_t preprocessor_create_task(zbx_preprocessing_manager_t *manage
else
THIS_SHOULD_NEVER_HAPPEN;
+ if (NULL != (vault = (zbx_preproc_history_t *)zbx_hashset_search(&manager->history_cache,
+ &request->value.itemid)))
+ {
+ phistory = &vault->history;
+ }
+ else
+ phistory = NULL;
+
size = zbx_preprocessor_pack_task(task, request->value.itemid, request->value_type, request->value.ts, &value,
- (zbx_item_history_value_t *)zbx_hashset_search(&manager->history_cache, &request->value.itemid),
- request->steps, request->steps_num);
+ phistory, request->steps, request->steps_num);
return size;
}
@@ -854,33 +845,38 @@ static void preprocessor_add_result(zbx_preprocessing_manager_t *manager, zbx_ip
zbx_preprocessing_request_t *request;
zbx_variant_t value;
char *error;
- zbx_item_history_value_t *history_value, *cached_value;
zbx_delta_item_index_t *index;
+ zbx_vector_ptr_t history;
+ zbx_preproc_history_t *vault;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
worker = preprocessor_get_worker_by_client(manager, client);
request = (zbx_preprocessing_request_t *)worker->queue_item->data;
- zbx_preprocessor_unpack_result(&value, &history_value, &error, message->data);
+ zbx_vector_ptr_create(&history);
+ zbx_preprocessor_unpack_result(&value, &history, &error, message->data);
- if (NULL != history_value)
+ if (NULL != (vault = (zbx_preproc_history_t *)zbx_hashset_search(&manager->history_cache,
+ &request->value.itemid)))
{
- history_value->itemid = request->value.itemid;
- history_value->value_type = request->value_type;
+ zbx_vector_ptr_clear_ext(&vault->history, (zbx_clean_func_t)zbx_preproc_op_history_free);
+ }
- if (NULL != (cached_value = (zbx_item_history_value_t *)zbx_hashset_search(&manager->history_cache, history_value)))
+ if (0 != history.values_num)
+ {
+ if (NULL == vault)
{
- if (0 < zbx_timespec_compare(&history_value->timestamp, &cached_value->timestamp))
- {
- /* history_value can only be numeric so it can be copied without extra memory */
- /* allocation */
- cached_value->timestamp = history_value->timestamp;
- cached_value->value = history_value->value;
- }
+ zbx_preproc_history_t history_local;
+
+ history_local.itemid = request->value.itemid;
+ vault = (zbx_preproc_history_t *)zbx_hashset_insert(&manager->history_cache, &history_local,
+ sizeof(history_local));
+ zbx_vector_ptr_create(&vault->history);
}
- else
- zbx_hashset_insert(&manager->history_cache, history_value, sizeof(zbx_item_history_value_t));
+
+ zbx_vector_ptr_append_array(&vault->history, history.values, history.values_num);
+ zbx_vector_ptr_clear(&history);
}
request->state = REQUEST_STATE_DONE;
@@ -901,13 +897,14 @@ static void preprocessor_add_result(zbx_preprocessing_manager_t *manager, zbx_ip
worker->queue_item = NULL;
zbx_variant_clear(&value);
- zbx_free(history_value);
manager->preproc_num--;
preprocessor_assign_tasks(manager);
preprocessing_flush_queue(manager);
+ zbx_vector_ptr_destroy(&history);
+
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
diff --git a/src/zabbix_server/preprocessor/preproc_worker.c b/src/zabbix_server/preprocessor/preproc_worker.c
index 7ed797fbf98..01ce364d4de 100644
--- a/src/zabbix_server/preprocessor/preproc_worker.c
+++ b/src/zabbix_server/preprocessor/preproc_worker.c
@@ -28,6 +28,7 @@
#include "sysinfo.h"
#include "preproc_worker.h"
#include "item_preproc.h"
+#include "preproc_history.h"
extern unsigned char process_type, program_type;
extern int server_num, process_num;
@@ -47,50 +48,56 @@ static void worker_preprocess_value(zbx_ipc_socket_t *socket, zbx_ipc_message_t
zbx_uint32_t size = 0;
unsigned char *data = NULL, value_type;
zbx_uint64_t itemid;
- zbx_variant_t value, value_num;
+ zbx_variant_t value;
int i, steps_num;
char *error = NULL;
zbx_timespec_t *ts;
- zbx_item_history_value_t *history_value, history_value_local;
zbx_preproc_op_t *steps;
+ zbx_vector_ptr_t history_in, history_out;
+ const zbx_preproc_op_history_t *ophistory;
- zbx_preprocessor_unpack_task(&itemid, &value_type, &ts, &value, &history_value, &steps, &steps_num,
+ zbx_vector_ptr_create(&history_in);
+ zbx_vector_ptr_create(&history_out);
+
+ zbx_preprocessor_unpack_task(&itemid, &value_type, &ts, &value, &history_in, &steps, &steps_num,
message->data);
for (i = 0; i < steps_num; i++)
{
zbx_preproc_op_t *op = &steps[i];
+ zbx_variant_t history_value;
+ zbx_timespec_t history_ts;
- if ((ZBX_PREPROC_DELTA_VALUE == op->type || ZBX_PREPROC_DELTA_SPEED == op->type) &&
- NULL == history_value)
+ if (NULL != (ophistory = zbx_preproc_history_get_value(&history_in, op->type)))
{
- if (FAIL != zbx_item_preproc_convert_value_to_numeric(&value_num, &value, value_type, &error))
- {
- history_value_local.timestamp = *ts;
- zbx_variant_set_variant(&history_value_local.value, &value_num);
- history_value = &history_value_local;
- }
-
- zbx_variant_clear(&value);
- break;
+ history_value = ophistory->value;
+ history_ts = ophistory->ts;
+ }
+ else
+ {
+ zbx_variant_set_none(&history_value);
+ history_ts.sec = 0;
+ history_ts.ns = 0;
}
- if (SUCCEED != zbx_item_preproc(i + 1, value_type, &value, ts, op, history_value, &error))
+ if (SUCCEED != zbx_item_preproc(i + 1, value_type, &value, ts, op, &history_value, &history_ts, &error))
break;
+ if (ZBX_VARIANT_NONE != history_value.type)
+ zbx_preproc_history_set_value(&history_out, op->type, &history_value, &history_ts);
+
+ zbx_variant_clear(&history_value);
+
if (ZBX_VARIANT_NONE == value.type)
break;
}
- size = zbx_preprocessor_pack_result(&data, &value, history_value, error);
+ size = zbx_preprocessor_pack_result(&data, &value, &history_out, error);
zbx_variant_clear(&value);
zbx_free(error);
zbx_free(ts);
zbx_free(steps);
- if (history_value != &history_value_local)
- zbx_free(history_value);
-
if (FAIL == zbx_ipc_socket_write(socket, ZBX_IPC_PREPROCESSOR_RESULT, data, size))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot send preprocessing result");
@@ -98,6 +105,12 @@ static void worker_preprocess_value(zbx_ipc_socket_t *socket, zbx_ipc_message_t
}
zbx_free(data);
+
+ zbx_vector_ptr_clear_ext(&history_out, (zbx_clean_func_t)zbx_preproc_op_history_free);
+ zbx_vector_ptr_destroy(&history_out);
+
+ zbx_vector_ptr_clear_ext(&history_in, (zbx_clean_func_t)zbx_preproc_op_history_free);
+ zbx_vector_ptr_destroy(&history_in);
}
ZBX_THREAD_ENTRY(preprocessing_worker_thread, args)
diff --git a/src/zabbix_server/preprocessor/preprocessing.c b/src/zabbix_server/preprocessor/preprocessing.c
index bd76aabfc19..fba4ad704a8 100644
--- a/src/zabbix_server/preprocessor/preprocessing.c
+++ b/src/zabbix_server/preprocessor/preprocessing.c
@@ -26,6 +26,7 @@
#include "preproc.h"
#include "preprocessing.h"
+#include "preproc_history.h"
#define PACKED_FIELD_RAW 0
#define PACKED_FIELD_STRING 1
@@ -147,6 +148,7 @@ static zbx_uint32_t preprocessor_pack_value(zbx_ipc_message_t *message, zbx_prep
if (NULL != value->result)
{
+
*offset++ = PACKED_FIELD(&value->result->lastlogsize, sizeof(zbx_uint64_t));
*offset++ = PACKED_FIELD(&value->result->ui64, sizeof(zbx_uint64_t));
*offset++ = PACKED_FIELD(&value->result->dbl, sizeof(double));
@@ -183,7 +185,7 @@ static zbx_uint32_t preprocessor_pack_value(zbx_ipc_message_t *message, zbx_prep
* value_type - [IN] item value type *
* ts - [IN] value timestamp *
* value - [IN] item value *
- * history_value - [IN] history data for delta preprocessing *
+ * history - [IN] history data (can be NULL) *
* steps - [IN] preprocessing steps *
* steps_num - [IN] preprocessing step count *
* *
@@ -191,21 +193,24 @@ static zbx_uint32_t preprocessor_pack_value(zbx_ipc_message_t *message, zbx_prep
* *
******************************************************************************/
zbx_uint32_t zbx_preprocessor_pack_task(unsigned char **data, zbx_uint64_t itemid, unsigned char value_type,
- zbx_timespec_t *ts, zbx_variant_t *value, zbx_item_history_value_t *history_value,
+ zbx_timespec_t *ts, zbx_variant_t *value, const zbx_vector_ptr_t *history,
const zbx_preproc_op_t *steps, int steps_num)
{
zbx_packed_field_t *offset, *fields;
- unsigned char ts_marker, history_marker;
+ unsigned char ts_marker;
zbx_uint32_t size;
int i;
zbx_ipc_message_t message;
+ unsigned char history_num;
+
+ history_num = (NULL != history ? history->values_num : 0);
/* 14 is a max field count (without preprocessing step fields) */
- fields = (zbx_packed_field_t *)zbx_malloc(NULL, (14 + steps_num * 4) * sizeof(zbx_packed_field_t));
+ fields = (zbx_packed_field_t *)zbx_malloc(NULL, (10 + steps_num * 4 + history_num * 5)
+ * sizeof(zbx_packed_field_t));
offset = fields;
ts_marker = (NULL != ts);
- history_marker = (NULL != history_value);
*offset++ = PACKED_FIELD(&itemid, sizeof(zbx_uint64_t));
*offset++ = PACKED_FIELD(&value_type, sizeof(unsigned char));
@@ -237,28 +242,34 @@ zbx_uint32_t zbx_preprocessor_pack_task(unsigned char **data, zbx_uint64_t itemi
THIS_SHOULD_NEVER_HAPPEN;
}
- *offset++ = PACKED_FIELD(&history_marker, sizeof(unsigned char));
- if (NULL != history_value)
+ *offset++ = PACKED_FIELD(&history_num, sizeof(unsigned char));
+ for (i = 0; i < history_num; i++)
{
- *offset++ = PACKED_FIELD(&history_value->value_type, sizeof(unsigned char));
- *offset++ = PACKED_FIELD(&history_value->value.type, sizeof(unsigned char));
+ zbx_preproc_op_history_t *ophistory = (zbx_preproc_op_history_t *)history->values[i];
+
+ *offset++ = PACKED_FIELD(&ophistory->type, sizeof(unsigned char));
+ *offset++ = PACKED_FIELD(&ophistory->value.type, sizeof(unsigned char));
- switch (history_value->value.type)
+ switch (ophistory->value.type)
{
case ZBX_VARIANT_UI64:
- *offset++ = PACKED_FIELD(&history_value->value.data.ui64, sizeof(zbx_uint64_t));
+ *offset++ = PACKED_FIELD(&ophistory->value.data.ui64, sizeof(zbx_uint64_t));
break;
case ZBX_VARIANT_DBL:
- *offset++ = PACKED_FIELD(&history_value->value.data.dbl, sizeof(double));
+ *offset++ = PACKED_FIELD(&ophistory->value.data.dbl, sizeof(double));
+ break;
+
+ case ZBX_VARIANT_STR:
+ *offset++ = PACKED_FIELD(ophistory->value.data.str, 0);
break;
default:
THIS_SHOULD_NEVER_HAPPEN;
}
- *offset++ = PACKED_FIELD(&history_value->timestamp.sec, sizeof(int));
- *offset++ = PACKED_FIELD(&history_value->timestamp.ns, sizeof(int));
+ *offset++ = PACKED_FIELD(&ophistory->ts.sec, sizeof(int));
+ *offset++ = PACKED_FIELD(&ophistory->ts.ns, sizeof(int));
}
*offset++ = PACKED_FIELD(&steps_num, sizeof(int));
@@ -288,22 +299,30 @@ zbx_uint32_t zbx_preprocessor_pack_task(unsigned char **data, zbx_uint64_t itemi
* *
* Parameters: data - [OUT] memory buffer for packed data *
* value - [IN] result value *
- * history_value - [IN] item history data *
+ * history - [IN] item history data *
* error - [IN] preprocessing error *
* *
* Return value: size of packed data *
* *
******************************************************************************/
zbx_uint32_t zbx_preprocessor_pack_result(unsigned char **data, zbx_variant_t *value,
- zbx_item_history_value_t *history_value, char *error)
+ const zbx_vector_ptr_t *history, char *error)
{
zbx_packed_field_t *offset, fields[8]; /* 8 - max field count */
- unsigned char history_marker;
+ unsigned char history_num;
zbx_uint32_t size;
zbx_ipc_message_t message;
+ int i;
offset = fields;
- history_marker = (NULL != history_value);
+
+ if (255 < history->values_num)
+ {
+ THIS_SHOULD_NEVER_HAPPEN;
+ exit(EXIT_FAILURE);
+ }
+
+ history_num = history->values_num;
*offset++ = PACKED_FIELD(&value->type, sizeof(unsigned char));
@@ -322,28 +341,35 @@ zbx_uint32_t zbx_preprocessor_pack_result(unsigned char **data, zbx_variant_t *v
break;
}
- *offset++ = PACKED_FIELD(&history_marker, sizeof(unsigned char));
+ *offset++ = PACKED_FIELD(&history_num, sizeof(unsigned char));
- if (NULL != history_value)
+ for (i = 0; i < history_num; i++)
{
- *offset++ = PACKED_FIELD(&history_value->value.type, sizeof(unsigned char));
+ zbx_preproc_op_history_t *ophistory = (zbx_preproc_op_history_t *)history->values[i];
- switch (history_value->value.type)
+ *offset++ = PACKED_FIELD(&ophistory->type, sizeof(unsigned char));
+ *offset++ = PACKED_FIELD(&ophistory->value.type, sizeof(unsigned char));
+
+ switch (ophistory->value.type)
{
case ZBX_VARIANT_UI64:
- *offset++ = PACKED_FIELD(&history_value->value.data.ui64, sizeof(zbx_uint64_t));
+ *offset++ = PACKED_FIELD(&ophistory->value.data.ui64, sizeof(zbx_uint64_t));
break;
case ZBX_VARIANT_DBL:
- *offset++ = PACKED_FIELD(&history_value->value.data.dbl, sizeof(double));
+ *offset++ = PACKED_FIELD(&ophistory->value.data.dbl, sizeof(double));
+ break;
+
+ case ZBX_VARIANT_STR:
+ *offset++ = PACKED_FIELD(ophistory->value.data.str, 0);
break;
default:
THIS_SHOULD_NEVER_HAPPEN;
}
- *offset++ = PACKED_FIELD(&history_value->timestamp.sec, sizeof(int));
- *offset++ = PACKED_FIELD(&history_value->timestamp.ns, sizeof(int));
+ *offset++ = PACKED_FIELD(&ophistory->ts.sec, sizeof(int));
+ *offset++ = PACKED_FIELD(&ophistory->ts.ns, sizeof(int));
}
*offset++ = PACKED_FIELD(error, 0);
@@ -436,20 +462,19 @@ zbx_uint32_t zbx_preprocessor_unpack_value(zbx_preproc_item_value_t *value, unsi
* value_type - [OUT] item value type *
* ts - [OUT] value timestamp *
* value - [OUT] item value *
- * history_value - [OUT] history data for delta preprocessing *
+ * history - [OUT] history data *
* steps - [OUT] preprocessing steps *
* steps_num - [OUT] preprocessing step count *
* data - [IN] IPC data buffer *
* *
******************************************************************************/
void zbx_preprocessor_unpack_task(zbx_uint64_t *itemid, unsigned char *value_type, zbx_timespec_t **ts,
- zbx_variant_t *value, zbx_item_history_value_t **history_value, zbx_preproc_op_t **steps,
+ zbx_variant_t *value, zbx_vector_ptr_t *history, zbx_preproc_op_t **steps,
int *steps_num, const unsigned char *data)
{
zbx_uint32_t value_len;
const unsigned char *offset = data;
- unsigned char ts_marker, history_marker;
- zbx_item_history_value_t *hvalue = NULL;
+ unsigned char ts_marker, history_num;
zbx_timespec_t *timespec = NULL;
int i;
@@ -486,33 +511,43 @@ void zbx_preprocessor_unpack_task(zbx_uint64_t *itemid, unsigned char *value_typ
THIS_SHOULD_NEVER_HAPPEN;
}
- offset += zbx_deserialize_char(offset, &history_marker);
- if (0 != history_marker)
- {
- hvalue = (zbx_item_history_value_t *)zbx_malloc(NULL, sizeof(zbx_item_history_value_t));
+ offset += zbx_deserialize_char(offset, &history_num);
- offset += zbx_deserialize_char(offset, &hvalue->value_type);
- offset += zbx_deserialize_char(offset, &hvalue->value.type);
+ if (0 != history_num)
+ {
+ zbx_vector_ptr_reserve(history, history_num);
- switch (hvalue->value.type)
+ for (i = 0; i < history_num; i++)
{
- case ZBX_VARIANT_UI64:
- offset += zbx_deserialize_uint64(offset, &hvalue->value.data.ui64);
- break;
+ zbx_preproc_op_history_t *ophistory;
- case ZBX_VARIANT_DBL:
- offset += zbx_deserialize_double(offset, &hvalue->value.data.dbl);
- break;
+ ophistory = zbx_malloc(NULL, sizeof(zbx_preproc_op_history_t));
- default:
- THIS_SHOULD_NEVER_HAPPEN;
- }
+ offset += zbx_deserialize_char(offset, &ophistory->type);
+ offset += zbx_deserialize_char(offset, &ophistory->value.type);
+
+ switch (ophistory->value.type)
+ {
+ case ZBX_VARIANT_UI64:
+ offset += zbx_deserialize_uint64(offset, &ophistory->value.data.ui64);
+ break;
+ case ZBX_VARIANT_DBL:
+ offset += zbx_deserialize_double(offset, &ophistory->value.data.dbl);
+ break;
+ case ZBX_VARIANT_STR:
+ offset += zbx_deserialize_str(offset, &ophistory->value.data.str, value_len);
+ break;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+ }
- offset += zbx_deserialize_int(offset, &hvalue->timestamp.sec);
- offset += zbx_deserialize_int(offset, &hvalue->timestamp.ns);
+ offset += zbx_deserialize_int(offset, &ophistory->ts.sec);
+ offset += zbx_deserialize_int(offset, &ophistory->ts.ns);
+
+ zbx_vector_ptr_append(history, ophistory);
+ }
}
- *history_value = hvalue;
offset += zbx_deserialize_int(offset, steps_num);
if (0 < *steps_num)
{
@@ -536,18 +571,17 @@ void zbx_preprocessor_unpack_task(zbx_uint64_t *itemid, unsigned char *value_typ
* Purpose: unpack preprocessing task data from IPC data buffer *
* *
* Parameters: value - [OUT] result value *
- * history_value - [OUT] item history data *
+ * history - [OUT] item history data *
* error - [OUT] preprocessing error *
* data - [IN] IPC data buffer *
* *
******************************************************************************/
-void zbx_preprocessor_unpack_result(zbx_variant_t *value, zbx_item_history_value_t **history_value, char **error,
+void zbx_preprocessor_unpack_result(zbx_variant_t *value, zbx_vector_ptr_t *history, char **error,
const unsigned char *data)
{
zbx_uint32_t value_len;
const unsigned char *offset = data;
- unsigned char history_marker;
- zbx_item_history_value_t *hvalue = NULL;
+ unsigned char history_num;
offset += zbx_deserialize_char(offset, &value->type);
@@ -566,32 +600,43 @@ void zbx_preprocessor_unpack_result(zbx_variant_t *value, zbx_item_history_value
break;
}
- offset += zbx_deserialize_char(offset, &history_marker);
- if (0 != history_marker)
+ offset += zbx_deserialize_char(offset, &history_num);
+ if (0 != history_num)
{
- hvalue = (zbx_item_history_value_t *)zbx_malloc(NULL, sizeof(zbx_item_history_value_t));
+ int i;
- offset += zbx_deserialize_char(offset, &hvalue->value.type);
+ zbx_vector_ptr_reserve(history, history_num);
- switch (hvalue->value.type)
+ for (i = 0; i < history_num; i++)
{
- case ZBX_VARIANT_UI64:
- offset += zbx_deserialize_uint64(offset, &hvalue->value.data.ui64);
- break;
+ zbx_preproc_op_history_t *ophistory;
- case ZBX_VARIANT_DBL:
- offset += zbx_deserialize_double(offset, &hvalue->value.data.dbl);
- break;
+ ophistory = zbx_malloc(NULL, sizeof(zbx_preproc_op_history_t));
- default:
- THIS_SHOULD_NEVER_HAPPEN;
- }
+ offset += zbx_deserialize_char(offset, &ophistory->type);
+ offset += zbx_deserialize_char(offset, &ophistory->value.type);
- offset += zbx_deserialize_int(offset, &hvalue->timestamp.sec);
- offset += zbx_deserialize_int(offset, &hvalue->timestamp.ns);
- }
+ switch (ophistory->value.type)
+ {
+ case ZBX_VARIANT_UI64:
+ offset += zbx_deserialize_uint64(offset, &ophistory->value.data.ui64);
+ break;
+ case ZBX_VARIANT_DBL:
+ offset += zbx_deserialize_double(offset, &ophistory->value.data.dbl);
+ break;
+ case ZBX_VARIANT_STR:
+ offset += zbx_deserialize_str(offset, &ophistory->value.data.str, value_len);
+ break;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+ }
+
+ offset += zbx_deserialize_int(offset, &ophistory->ts.sec);
+ offset += zbx_deserialize_int(offset, &ophistory->ts.ns);
- *history_value = hvalue;
+ zbx_vector_ptr_append(history, ophistory);
+ }
+ }
(void)zbx_deserialize_str(offset, error, value_len);
}
diff --git a/src/zabbix_server/preprocessor/preprocessing.h b/src/zabbix_server/preprocessor/preprocessing.h
index 202ae6a55e1..23063ba7754 100644
--- a/src/zabbix_server/preprocessor/preprocessing.h
+++ b/src/zabbix_server/preprocessor/preprocessing.h
@@ -45,16 +45,16 @@ typedef struct
zbx_preproc_item_value_t;
zbx_uint32_t zbx_preprocessor_pack_task(unsigned char **data, zbx_uint64_t itemid, unsigned char value_type,
- zbx_timespec_t *ts, zbx_variant_t *value, zbx_item_history_value_t *history_value,
+ zbx_timespec_t *ts, zbx_variant_t *value, const zbx_vector_ptr_t *history,
const zbx_preproc_op_t *steps, int steps_num);
zbx_uint32_t zbx_preprocessor_pack_result(unsigned char **data, zbx_variant_t *value,
- zbx_item_history_value_t *history_value, char *error);
+ const zbx_vector_ptr_t *history, char *error);
zbx_uint32_t zbx_preprocessor_unpack_value(zbx_preproc_item_value_t *value, unsigned char *data);
void zbx_preprocessor_unpack_task(zbx_uint64_t *itemid, unsigned char *value_type, zbx_timespec_t **ts,
- zbx_variant_t *value, zbx_item_history_value_t **history_value, zbx_preproc_op_t **steps,
+ zbx_variant_t *value, zbx_vector_ptr_t *history, zbx_preproc_op_t **steps,
int *steps_num, const unsigned char *data);
-void zbx_preprocessor_unpack_result(zbx_variant_t *value, zbx_item_history_value_t **history_value,
- char **error, const unsigned char *data);
+void zbx_preprocessor_unpack_result(zbx_variant_t *value, zbx_vector_ptr_t *history, char **error,
+ const unsigned char *data);
#endif /* ZABBIX_PREPROCESSING_H */
diff --git a/tests/zabbix_server/preprocessor/zbx_item_preproc.c b/tests/zabbix_server/preprocessor/zbx_item_preproc.c
index 42eef3902e2..8c5dd999295 100644
--- a/tests/zabbix_server/preprocessor/zbx_item_preproc.c
+++ b/tests/zabbix_server/preprocessor/zbx_item_preproc.c
@@ -90,13 +90,13 @@ static int str_to_preproc_error_handler(const char *str)
return FAIL;
}
-static void read_value(const char *path, unsigned char *value_type, zbx_timespec_t *ts,
- zbx_variant_t *value)
+static void read_value(const char *path, unsigned char *value_type, zbx_variant_t *value, zbx_timespec_t *ts)
{
zbx_mock_handle_t handle;
handle = zbx_mock_get_parameter_handle(path);
- *value_type = zbx_mock_str_to_value_type(zbx_mock_get_object_member_string(handle, "value_type"));
+ if (NULL != value_type)
+ *value_type = zbx_mock_str_to_value_type(zbx_mock_get_object_member_string(handle, "value_type"));
zbx_strtime_to_timespec(zbx_mock_get_object_member_string(handle, "time"), ts);
zbx_variant_set_str(value, zbx_strdup(NULL, zbx_mock_get_object_member_string(handle, "data")));
}
@@ -126,27 +126,30 @@ static void read_step(const char *path, zbx_preproc_op_t *op)
void zbx_mock_test_entry(void **state)
{
- zbx_variant_t value;
+ zbx_variant_t value, history_value;
unsigned char value_type;
- zbx_timespec_t ts;
- zbx_item_history_value_t history, *phistory = NULL;
+ zbx_timespec_t ts, history_ts, expected_history_ts;
zbx_preproc_op_t op;
int returned_ret, expected_ret;
char *error = NULL;
ZBX_UNUSED(state);
- read_value("in.value", &value_type, &ts, &value);
+ read_value("in.value", &value_type, &value, &ts);
read_step("in.step", &op);
if (ZBX_MOCK_SUCCESS == zbx_mock_parameter_exists("in.history"))
{
- history.itemid = 0;
- read_value("in.history", &history.value_type, &history.timestamp, &history.value);
- phistory = &history;
+ read_value("in.history", NULL, &history_value, &history_ts);
+ }
+ else
+ {
+ zbx_variant_set_none(&history_value);
+ history_ts.sec = 0;
+ history_ts.ns = 0;
}
- returned_ret = zbx_item_preproc(0, value_type, &value, &ts, &op, phistory, &error);
+ returned_ret = zbx_item_preproc(0, value_type, &value, &ts, &op, &history_value, &history_ts, &error);
expected_ret = zbx_mock_str_to_return_code(zbx_mock_get_parameter_string("out.return"));
zbx_mock_assert_result_eq("zbx_item_preproc() return", expected_ret, returned_ret);
@@ -167,6 +170,25 @@ void zbx_mock_test_entry(void **state)
if (ZBX_VARIANT_NONE != value.type)
fail_msg("expected empty value, but got %s", zbx_variant_value_desc(&value));
}
+
+ if (ZBX_MOCK_SUCCESS == zbx_mock_parameter_exists("out.history"))
+ {
+ if (ZBX_VARIANT_NONE == history_value.type)
+ fail_msg("preprocessing history was empty value");
+
+ zbx_variant_convert(&history_value, ZBX_VARIANT_STR);
+ del_zeros(history_value.data.str);
+ zbx_mock_assert_str_eq("preprocessing step history value",
+ zbx_mock_get_parameter_string("out.history.data"), history_value.data.str);
+
+ zbx_strtime_to_timespec(zbx_mock_get_parameter_string("out.history.time"), &expected_history_ts);
+ zbx_mock_assert_timespec_eq("preprocessing step history time", &expected_history_ts, &history_ts);
+ }
+ else
+ {
+ if (ZBX_VARIANT_NONE != history_value.type)
+ fail_msg("expected empty value, but got %s", zbx_variant_value_desc(&history_value));
+ }
}
if (FAIL == returned_ret && ZBX_MOCK_SUCCESS == zbx_mock_parameter_exists("out.error"))
diff --git a/tests/zabbix_server/preprocessor/zbx_item_preproc.yaml b/tests/zabbix_server/preprocessor/zbx_item_preproc.yaml
index d1c5f09ca4f..127ccbe057b 100644
--- a/tests/zabbix_server/preprocessor/zbx_item_preproc.yaml
+++ b/tests/zabbix_server/preprocessor/zbx_item_preproc.yaml
@@ -577,6 +577,9 @@ in:
out:
return: SUCCEED
value: 5
+ history:
+ data: 10
+ time: 2017-10-29 03:15:00 +03:00
---
test case: deltavalue(-4.5, 5.5)
in:
@@ -593,6 +596,9 @@ in:
out:
return: SUCCEED
value: 10
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 5.5
---
test case: deltavalue(10, 10)
in:
@@ -609,6 +615,9 @@ in:
out:
return: SUCCEED
value: 0
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 10
---
test case: deltavalue(10, 9)
in:
@@ -624,6 +633,9 @@ in:
type: ZBX_PREPROC_DELTA_VALUE
out:
return: SUCCEED
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 0
---
test case: deltavalue(0, 1.5)
in:
@@ -640,6 +652,9 @@ in:
out:
return: SUCCEED
value: 1.5
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 1.5
---
test case: deltaspeed(2, 1, 10s)
in:
@@ -655,6 +670,9 @@ in:
type: ZBX_PREPROC_DELTA_SPEED
out:
return: SUCCEED
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 1
---
test case: deltaspeed(1, 2, -10s)
in:
@@ -670,6 +688,9 @@ in:
type: ZBX_PREPROC_DELTA_SPEED
out:
return: SUCCEED
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 2
---
test case: deltaspeed(1, 2, 10s)
in:
@@ -686,6 +707,9 @@ in:
out:
return: SUCCEED
value: 0.1
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 2
---
test case: deltaspeed(2, 3, 10s)
in:
@@ -702,6 +726,9 @@ in:
out:
return: SUCCEED
value: 0
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 3
---
test case: deltaspeed(2, 3, 1s)
in:
@@ -718,6 +745,9 @@ in:
out:
return: SUCCEED
value: 1
+ history:
+ time: 2017-10-29 03:15:00 +03:00
+ data: 3
---
test case: xpath1
in: