From d94743a44e1307fa66f06ab574c58e042566c09c Mon Sep 17 00:00:00 2001 From: Andris Zeila Date: Fri, 4 Nov 2022 11:19:57 +0200 Subject: .......PS. [ZBXNEXT-8040] added object based json parsing and jsonpath indexing for simple expressions Merge in ZBX/zabbix from feature/ZBXNEXT-8040-6.3 to master * commit '6835ef59b1bef2bbe783f90b8399bee0f1f93ab8': .......PS. [ZBXNEXT-8040] fixed warnings .......PS. [ZBXNEXT-8040] remove duplicate indexes/names when compiling jsonpath .......PS. [ZBXNEXT-8040] fixed jsonpath indexing when relative path is on comparison right side .......PS. [ZBXNEXT-8040] fixed invalid nested jsonpath in expression .......PS. [ZBXNEXT-8040] ported jsonpath 'first found' optimization from ZBXNEXT-8009 .......PS. [ZBXNEXT-8040] fixed memory leak in json object index .D........ [ZBXNEXT-8040] added changelog entry .......... [ZBXNEXT-8040] added missing file .......PS. [ZBXNEXT-8040] addded json object caching in jsonpath preprocessing step .......... [ZBXNEXT-8040] updated jsonpath cmocka tests to use directly zbx_jsonobj_query and test it twice to check index reuse .......PS. [ZBXNEXT-8040] added support for more complex expression indexing .......PS. [ZBXNEXT-8040] added object based json parser and json path processing with indexing (cherry picked from commit e13326c4e6c1dfa1e5bd7906b72d636053140128) --- src/zabbix_server/preprocessor/item_preproc.c | 73 ++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 14 deletions(-) (limited to 'src/zabbix_server/preprocessor/item_preproc.c') diff --git a/src/zabbix_server/preprocessor/item_preproc.c b/src/zabbix_server/preprocessor/item_preproc.c index 2748cade102..12d81aa4bff 100644 --- a/src/zabbix_server/preprocessor/item_preproc.c +++ b/src/zabbix_server/preprocessor/item_preproc.c @@ -819,7 +819,8 @@ static int item_preproc_regsub(zbx_variant_t *value, const char *params, char ** * * * Purpose: execute jsonpath query * * * - * Parameters: value - [IN/OUT] the value to process * + * Parameters: cache - [IN] the preprocessing cache * + * value - [IN/OUT] the value to process * * params - [IN] the operation parameters * * errmsg - [OUT] error message * * * @@ -827,18 +828,59 @@ static int item_preproc_regsub(zbx_variant_t *value, const char *params, char ** * FAIL - otherwise * * * ******************************************************************************/ -static int item_preproc_jsonpath_op(zbx_variant_t *value, const char *params, char **errmsg) +static int item_preproc_jsonpath_op(zbx_preproc_cache_t *cache, zbx_variant_t *value, const char *params, + char **errmsg) { - struct zbx_json_parse jp; - char *data = NULL; + char *data = NULL; - if (FAIL == item_preproc_convert_value(value, ZBX_VARIANT_STR, errmsg)) - return FAIL; + if (NULL == cache) + { + zbx_jsonobj_t obj; + + if (FAIL == item_preproc_convert_value(value, ZBX_VARIANT_STR, errmsg)) + return FAIL; - if (FAIL == zbx_json_open(value->data.str, &jp) || FAIL == zbx_jsonpath_query(&jp, params, &data)) + if (FAIL == zbx_jsonobj_open(value->data.str, &obj)) + { + *errmsg = zbx_strdup(*errmsg, zbx_json_strerror()); + return FAIL; + } + + if (FAIL == zbx_jsonobj_query(&obj, params, &data)) + { + zbx_jsonobj_clear(&obj); + *errmsg = zbx_strdup(*errmsg, zbx_json_strerror()); + return FAIL; + } + + zbx_jsonobj_clear(&obj); + } + else { - *errmsg = zbx_strdup(*errmsg, zbx_json_strerror()); - return FAIL; + zbx_jsonobj_t *obj; + + if (NULL == (obj = (zbx_jsonobj_t *)zbx_preproc_cache_get(cache, ZBX_PREPROC_JSONPATH))) + { + if (FAIL == item_preproc_convert_value(value, ZBX_VARIANT_STR, errmsg)) + return FAIL; + + obj = (zbx_jsonobj_t *)zbx_malloc(NULL, sizeof(zbx_jsonobj_t)); + + if (SUCCEED != zbx_jsonobj_open(value->data.str, obj)) + { + *errmsg = zbx_strdup(*errmsg, zbx_json_strerror()); + zbx_free(obj); + return FAIL; + } + + zbx_preproc_cache_put(cache, ZBX_PREPROC_JSONPATH, obj); + } + + if (FAIL == zbx_jsonobj_query(obj, params, &data)) + { + *errmsg = zbx_strdup(*errmsg, zbx_json_strerror()); + return FAIL; + } } if (NULL == data) @@ -857,7 +899,8 @@ static int item_preproc_jsonpath_op(zbx_variant_t *value, const char *params, ch * * * Purpose: execute jsonpath query * * * - * Parameters: value - [IN/OUT] the value to process * + * Parameters: cache - [IN] the preprocessing cache * + * value - [IN/OUT] the value to process * * params - [IN] the operation parameters * * errmsg - [OUT] error message * * * @@ -865,11 +908,12 @@ static int item_preproc_jsonpath_op(zbx_variant_t *value, const char *params, ch * FAIL - otherwise * * * ******************************************************************************/ -static int item_preproc_jsonpath(zbx_variant_t *value, const char *params, char **errmsg) +static int item_preproc_jsonpath(zbx_preproc_cache_t *cache, zbx_variant_t *value, const char *params, + char **errmsg) { char *err = NULL; - if (SUCCEED == item_preproc_jsonpath_op(value, params, &err)) + if (SUCCEED == item_preproc_jsonpath_op(cache, value, params, &err)) return SUCCEED; *errmsg = zbx_dsprintf(*errmsg, "cannot extract value from json by path \"%s\": %s", params, err); @@ -1456,7 +1500,8 @@ fail: * * * Purpose: parse Prometheus format metrics * * * - * Parameters: value - [IN/OUT] the value to process * + * Parameters: cache - [IN] the preprocessing cache * + * value - [IN/OUT] the value to process * * params - [IN] the operation parameters * * errmsg - [OUT] error message * * * @@ -2033,7 +2078,7 @@ int zbx_item_preproc(zbx_preproc_cache_t *cache, unsigned char value_type, zbx_v ret = item_preproc_xpath(value, op->params, error); break; case ZBX_PREPROC_JSONPATH: - ret = item_preproc_jsonpath(value, op->params, error); + ret = item_preproc_jsonpath(cache, value, op->params, error); break; case ZBX_PREPROC_VALIDATE_RANGE: ret = item_preproc_validate_range(value_type, value, op->params, error); -- cgit v1.2.3