1 /* 2 ** Zabbix 3 ** Copyright (C) 2001-2021 Zabbix SIA 4 ** 5 ** This program is free software; you can redistribute it and/or modify 6 ** it under the terms of the GNU General Public License as published by 7 ** the Free Software Foundation; either version 2 of the License, or 8 ** (at your option) any later version. 9 ** 10 ** This program is distributed in the hope that it will be useful, 11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 ** GNU General Public License for more details. 14 ** 15 ** You should have received a copy of the GNU General Public License 16 ** along with this program; if not, write to the Free Software 17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 **/ 19 20 #ifndef ZABBIX_ZBXEVAL_H 21 #define ZABBIX_ZBXEVAL_H 22 23 #include "common.h" 24 #include "zbxalgo.h" 25 #include "zbxvariant.h" 26 27 /* 28 * Token type flags (32 bits): 29 * | 6 bits | 4 bits | 22 bits | 30 * | token class | operator precedence | token type | 31 */ 32 #define ZBX_EVAL_CLASS_OPERAND (__UINT64_C(0x01) << 26) 33 #define ZBX_EVAL_CLASS_OPERATOR1 (__UINT64_C(0x02) << 26) 34 #define ZBX_EVAL_CLASS_OPERATOR2 (__UINT64_C(0x04) << 26) 35 #define ZBX_EVAL_CLASS_FUNCTION (__UINT64_C(0x08) << 26) 36 #define ZBX_EVAL_CLASS_SEPARATOR (__UINT64_C(0x10) << 26) 37 #define ZBX_EVAL_CLASS_PROPERTY (__UINT64_C(0x20) << 26) 38 #define ZBX_EVAL_CLASS_OPERATOR (ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_CLASS_OPERATOR2) 39 40 #define ZBX_EVAL_BEFORE_OPERAND (ZBX_EVAL_CLASS_OPERATOR | ZBX_EVAL_CLASS_SEPARATOR) 41 #define ZBX_EVAL_BEFORE_OPERATOR (ZBX_EVAL_CLASS_OPERAND | ZBX_EVAL_CLASS_PROPERTY) 42 43 #define ZBX_EVAL_OP_SET_PRECEDENCE(x) ((x) << 22) 44 #define ZBX_EVAL_OP_PRIORITY ZBX_EVAL_OP_SET_PRECEDENCE(0xf) 45 46 #define ZBX_EVAL_TOKEN_NOP (0) 47 #define ZBX_EVAL_TOKEN_OP_ADD (1 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(4)) 48 #define ZBX_EVAL_TOKEN_OP_SUB (2 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(4)) 49 #define ZBX_EVAL_TOKEN_OP_MUL (3 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(3)) 50 #define ZBX_EVAL_TOKEN_OP_DIV (4 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(3)) 51 #define ZBX_EVAL_TOKEN_OP_MINUS (5 | ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_OP_SET_PRECEDENCE(2)) 52 #define ZBX_EVAL_TOKEN_OP_EQ (6 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(7)) 53 #define ZBX_EVAL_TOKEN_OP_LT (7 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6)) 54 #define ZBX_EVAL_TOKEN_OP_GT (8 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6)) 55 #define ZBX_EVAL_TOKEN_OP_LE (9 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6)) 56 #define ZBX_EVAL_TOKEN_OP_GE (10 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6)) 57 #define ZBX_EVAL_TOKEN_OP_NE (11 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(7)) 58 #define ZBX_EVAL_TOKEN_OP_AND (12 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(11)) 59 #define ZBX_EVAL_TOKEN_OP_OR (13 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(12)) 60 #define ZBX_EVAL_TOKEN_OP_NOT (14 | ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_OP_SET_PRECEDENCE(2)) 61 #define ZBX_EVAL_TOKEN_VAR_NUM (15 | ZBX_EVAL_CLASS_OPERAND) 62 #define ZBX_EVAL_TOKEN_VAR_STR (16 | ZBX_EVAL_CLASS_OPERAND) 63 #define ZBX_EVAL_TOKEN_VAR_MACRO (17 | ZBX_EVAL_CLASS_OPERAND) 64 #define ZBX_EVAL_TOKEN_VAR_USERMACRO (18 | ZBX_EVAL_CLASS_OPERAND) 65 #define ZBX_EVAL_TOKEN_VAR_LLDMACRO (19 | ZBX_EVAL_CLASS_OPERAND) 66 #define ZBX_EVAL_TOKEN_FUNCTIONID (20 | ZBX_EVAL_CLASS_OPERAND) 67 #define ZBX_EVAL_TOKEN_FUNCTION (21 | ZBX_EVAL_CLASS_FUNCTION) 68 #define ZBX_EVAL_TOKEN_HIST_FUNCTION (22 | ZBX_EVAL_CLASS_FUNCTION) 69 #define ZBX_EVAL_TOKEN_GROUP_OPEN (23 | ZBX_EVAL_CLASS_SEPARATOR) 70 #define ZBX_EVAL_TOKEN_GROUP_CLOSE (24 | ZBX_EVAL_CLASS_OPERAND) 71 #define ZBX_EVAL_TOKEN_COMMA (25 | ZBX_EVAL_CLASS_SEPARATOR) 72 #define ZBX_EVAL_TOKEN_ARG_QUERY (26 | ZBX_EVAL_CLASS_OPERAND) 73 #define ZBX_EVAL_TOKEN_ARG_PERIOD (27 | ZBX_EVAL_CLASS_OPERAND) 74 #define ZBX_EVAL_TOKEN_ARG_NULL (28 | ZBX_EVAL_CLASS_OPERAND) 75 #define ZBX_EVAL_TOKEN_PROP_TAG (29 | ZBX_EVAL_CLASS_PROPERTY) 76 #define ZBX_EVAL_TOKEN_PROP_GROUP (30 | ZBX_EVAL_CLASS_PROPERTY) 77 #define ZBX_EVAL_TOKEN_EXCEPTION (31 | ZBX_EVAL_CLASS_FUNCTION) 78 79 /* token parsing rules */ 80 81 #define ZBX_EVAL_PARSE_MACRO __UINT64_C(0x00000001) 82 #define ZBX_EVAL_PARSE_USERMACRO __UINT64_C(0x00000002) 83 #define ZBX_EVAL_PARSE_LLDMACRO __UINT64_C(0x00000004) 84 #define ZBX_EVAL_PARSE_FUNCTIONID __UINT64_C(0x00000008) 85 #define ZBX_EVAL_PARSE_ITEM_QUERY __UINT64_C(0x00000010) 86 #define ZBX_EVAL_PARSE_CONST_INDEX __UINT64_C(0x00000020) 87 #define ZBX_EVAL_PARSE_COMPOUND_CONST __UINT64_C(0x00000040) 88 #define ZBX_EVAL_PARSE_MATH __UINT64_C(0x00000080) /* +, -, *, / */ 89 #define ZBX_EVAL_PARSE_COMPARE_EQ __UINT64_C(0x00000100) /* =, <> */ 90 #define ZBX_EVAL_PARSE_COMPARE_SORT __UINT64_C(0x00000200) /* <, <=, >, >= */ 91 #define ZBX_EVAL_PARSE_LOGIC __UINT64_C(0x00000400) /* or, and, not */ 92 #define ZBX_EVAL_PARSE_VAR_NUM __UINT64_C(0x00000800) /* number */ 93 #define ZBX_EVAL_PARSE_VAR_STR __UINT64_C(0x00001000) /* string */ 94 #define ZBX_EVAL_PARSE_GROUP __UINT64_C(0x00002000) /* (, ) */ 95 #define ZBX_EVAL_PARSE_FUNCTION_ARGS __UINT64_C(0x00004000) 96 #define ZBX_EVAL_PARSE_FUNCTION_NAME __UINT64_C(0x00008000) 97 #define ZBX_EVAL_PARSE_PROP_TAG __UINT64_C(0x00010000) /* 'tag' keyword in item query filter */ 98 #define ZBX_EVAL_PARSE_PROP_GROUP __UINT64_C(0x00020000) /* 'group' keyword in item query filter */ 99 100 #define ZBX_EVAL_PARSE_FUNCTION (ZBX_EVAL_PARSE_FUNCTION_NAME | ZBX_EVAL_PARSE_FUNCTION_ARGS |\ 101 ZBX_EVAL_PARSE_GROUP) 102 #define ZBX_EVAL_PARSE_COMPARE (ZBX_EVAL_PARSE_COMPARE_EQ | ZBX_EVAL_PARSE_COMPARE_SORT) 103 #define ZBX_EVAL_PARSE_VAR (ZBX_EVAL_PARSE_VAR_NUM | ZBX_EVAL_PARSE_VAR_STR) 104 #define ZBX_EVAL_PARSE_PROPERTY (ZBX_EVAL_PARSE_PROP_TAG | ZBX_EVAL_PARSE_PROP_GROUP) 105 106 /* expression parsing rules */ 107 108 #define ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION (ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO |\ 109 ZBX_EVAL_PARSE_FUNCTIONID | ZBX_EVAL_PARSE_FUNCTION |\ 110 ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE |\ 111 ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR) 112 113 #define ZBX_EVAL_PARSE_CALC_EXPRESSSION (ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO |\ 114 ZBX_EVAL_PARSE_ITEM_QUERY | ZBX_EVAL_PARSE_FUNCTION |\ 115 ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE |\ 116 ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR |\ 117 ZBX_EVAL_PARSE_COMPOUND_CONST) 118 119 #define ZBX_EVAL_PARSE_QUERY_EXPRESSION (ZBX_EVAL_PARSE_USERMACRO | ZBX_EVAL_PARSE_COMPARE_EQ |\ 120 ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_GROUP |\ 121 ZBX_EVAL_PARSE_VAR_STR | ZBX_EVAL_PARSE_PROPERTY) 122 123 #define ZBX_EVAL_PARSE_EXPRESSION_MACRO (ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO |\ 124 ZBX_EVAL_PARSE_ITEM_QUERY | ZBX_EVAL_PARSE_FUNCTION |\ 125 ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE |\ 126 ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR |\ 127 ZBX_EVAL_PARSE_COMPOUND_CONST) 128 /* expression composition rules */ 129 130 #define ZBX_EVAL_COMPOSE_LLD __UINT64_C(0x01000000) 131 #define ZBX_EVAL_COMPOSE_FUNCTIONID __UINT64_C(0x02000000) 132 #define ZBX_EVAL_COMPOSE_QUOTE __UINT64_C(0x04000000) 133 #define ZBX_EVAL_COMPOSE_MASK_ERROR __UINT64_C(0x08000000) 134 135 /* expression evaluation rules */ 136 137 #define ZBX_EVAL_PROCESS_ERROR __UINT64_C(0x000100000000) 138 139 /* composite rules */ 140 141 #define ZBX_EVAL_TRIGGER_EXPRESSION (ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION | \ 142 ZBX_EVAL_PARSE_CONST_INDEX | \ 143 ZBX_EVAL_PROCESS_ERROR) 144 145 #define ZBX_EVAL_TRIGGER_EXPRESSION_LLD (ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION | \ 146 ZBX_EVAL_PARSE_LLDMACRO | \ 147 ZBX_EVAL_COMPOSE_LLD | \ 148 ZBX_EVAL_COMPOSE_FUNCTIONID) 149 150 #define ZBX_EVAL_CALC_EXPRESSION_LLD (ZBX_EVAL_PARSE_CALC_EXPRESSSION | \ 151 ZBX_EVAL_PARSE_LLDMACRO | \ 152 ZBX_EVAL_COMPOSE_LLD) 153 154 #define ZBX_EVAL_EXPRESSION_MACRO_LLD (ZBX_EVAL_PARSE_EXPRESSION_MACRO | \ 155 ZBX_EVAL_PARSE_LLDMACRO | \ 156 ZBX_EVAL_COMPOSE_LLD) 157 158 #define ZBX_EVAL_QUERY_EXPRESSION_LLD (ZBX_EVAL_PARSE_QUERY_EXPRESSION | \ 159 ZBX_EVAL_PARSE_LLDMACRO | \ 160 ZBX_EVAL_COMPOSE_LLD) 161 162 typedef zbx_uint32_t zbx_token_type_t; 163 164 /****************************************************************************** 165 * * 166 * Typedef: zbx_eval_function_cb_t * 167 * * 168 * Purpose: define callback function to calculate custom functions * 169 * * 170 * Parameters: name - [IN] the function name (not zero terminated) * 171 * len - [IN] the function name length * 172 * args_num - [IN] the number of function arguments * 173 * args - [IN] an array of the function arguments. * 174 * data - [IN] the caller data used for function evaluation * 175 * ts - [IN] the function execution time * 176 * value - [OUT] the function return value * 177 * error - [OUT] the error message if function failed * 178 * * 179 * Return value: SUCCEED - the function was executed successfully * 180 * FAIL - otherwise * 181 * * 182 ******************************************************************************/ 183 typedef int (*zbx_eval_function_cb_t)(const char *name, size_t len, int args_num, const zbx_variant_t *args, 184 void *data, const zbx_timespec_t *ts, zbx_variant_t *value, char **error); 185 186 typedef struct 187 { 188 zbx_token_type_t type; 189 zbx_uint32_t opt; 190 zbx_strloc_t loc; 191 zbx_variant_t value; 192 } 193 zbx_eval_token_t; 194 195 ZBX_VECTOR_DECL(eval_token, zbx_eval_token_t) 196 197 typedef struct 198 { 199 const char *expression; 200 zbx_token_type_t last_token_type; 201 zbx_uint32_t const_index; 202 zbx_uint32_t functionid_index; 203 zbx_uint64_t rules; 204 zbx_timespec_t ts; 205 zbx_vector_eval_token_t stack; 206 zbx_vector_eval_token_t ops; 207 zbx_eval_function_cb_t common_func_cb; 208 zbx_eval_function_cb_t history_func_cb; 209 void *data_cb; 210 } 211 zbx_eval_context_t; 212 213 typedef int (*zbx_macro_resolve_func_t)(const char *str, size_t length, zbx_uint64_t *hostids, 214 int hostids_num, char **value, char **error); 215 216 int zbx_eval_parse_expression(zbx_eval_context_t *ctx, const char *expression, zbx_uint64_t rules, char **error); 217 void zbx_eval_init(zbx_eval_context_t *ctx); 218 void zbx_eval_clear(zbx_eval_context_t *ctx); 219 int zbx_eval_status(const zbx_eval_context_t *ctx); 220 size_t zbx_eval_serialize(const zbx_eval_context_t *ctx, zbx_mem_malloc_func_t malloc_func, unsigned char **data); 221 void zbx_eval_deserialize(zbx_eval_context_t *ctx, const char *expression, zbx_uint64_t rules, 222 const unsigned char *data); 223 void zbx_eval_compose_expression(const zbx_eval_context_t *ctx, char **expression); 224 int zbx_eval_execute(zbx_eval_context_t *ctx, const zbx_timespec_t *ts, zbx_variant_t *value, char **error); 225 int zbx_eval_execute_ext(zbx_eval_context_t *ctx, const zbx_timespec_t *ts, zbx_eval_function_cb_t common_func_cb, 226 zbx_eval_function_cb_t history_func_cb, void *data, zbx_variant_t *value, char **error); 227 void zbx_eval_get_functionids(zbx_eval_context_t *ctx, zbx_vector_uint64_t *functionids); 228 void zbx_eval_get_functionids_ordered(zbx_eval_context_t *ctx, zbx_vector_uint64_t *functionids); 229 int zbx_eval_expand_user_macros(const zbx_eval_context_t *ctx, zbx_uint64_t *hostids, int hostids_num, 230 zbx_macro_resolve_func_t resolver_cb, char **error); 231 void zbx_eval_set_exception(zbx_eval_context_t *ctx, char *message); 232 233 #define ZBX_EVAL_EXTRACT_FUNCTIONID 0x0001 234 #define ZBX_EVAL_EXTRACT_VAR_STR 0x0002 235 #define ZBX_EVAL_EXTRACT_VAR_MACRO 0x0004 236 237 #define ZBX_EVAL_EXCTRACT_ALL (ZBX_EVAL_EXTRACT_FUNCTIONID | ZBX_EVAL_EXTRACT_VAR_STR | ZBX_EVAL_EXTRACT_VAR_MACRO) 238 239 zbx_eval_context_t *zbx_eval_deserialize_dyn(const unsigned char *data, const char *expression, 240 zbx_uint64_t mask); 241 int zbx_eval_check_timer_functions(const zbx_eval_context_t *ctx); 242 void zbx_get_serialized_expression_functionids(const char *expression, const unsigned char *data, 243 zbx_vector_uint64_t *functionids); 244 void zbx_eval_get_constant(const zbx_eval_context_t *ctx, int index, char **value); 245 void zbx_eval_replace_functionid(zbx_eval_context_t *ctx, zbx_uint64_t old_functionid, zbx_uint64_t new_functionid); 246 int zbx_eval_validate_replaced_functionids(zbx_eval_context_t *ctx, char **error); 247 void zbx_eval_copy(zbx_eval_context_t *dst, const zbx_eval_context_t *src, const char *expression); 248 249 char *zbx_eval_format_function_error(const char *function, const char *host, const char *key, 250 const char *parameter, const char *error); 251 252 void zbx_eval_extract_item_refs(zbx_eval_context_t *ctx, zbx_vector_str_t *refs); 253 254 255 typedef struct 256 { 257 char *host; 258 char *key; 259 char *filter; 260 } 261 zbx_item_query_t; 262 263 size_t zbx_eval_parse_query(const char *str, size_t len, zbx_item_query_t *query); 264 void zbx_eval_clear_query(zbx_item_query_t *query); 265 266 void zbx_eval_prepare_filter(zbx_eval_context_t *ctx); 267 int zbx_eval_get_group_filter(zbx_eval_context_t *ctx, zbx_vector_str_t *groups, char **filter, char **error); 268 269 typedef int (*zbx_statistical_func_t)(zbx_vector_dbl_t *values, double *result, char **error); 270 271 int zbx_eval_calc_kurtosis(zbx_vector_dbl_t *values, double *result, char **error); 272 int zbx_eval_calc_mad(zbx_vector_dbl_t *values, double *result, char **error); 273 int zbx_eval_calc_skewness(zbx_vector_dbl_t *values, double *result, char **error); 274 int zbx_eval_calc_stddevpop(zbx_vector_dbl_t *values, double *result, char **error); 275 int zbx_eval_calc_stddevsamp(zbx_vector_dbl_t *values, double *result, char **error); 276 int zbx_eval_calc_sumofsquares(zbx_vector_dbl_t *values, double *result, char **error); 277 int zbx_eval_calc_varpop(zbx_vector_dbl_t *values, double *result, char **error); 278 int zbx_eval_calc_varsamp(zbx_vector_dbl_t *values, double *result, char **error); 279 280 #endif 281