/****************************************************************************** * * * Function: evaluate_aggregate * * * * Parameters: item - [IN] aggregated item * * grp_func - [IN] one of ZBX_GRP_FUNC_* * * groups - [IN] list of comma-separated host groups * * itemkey - [IN] item key to aggregate * * item_func - [IN] one of ZBX_DB_GET_HIST_* * * param - [IN] item_func parameter (optional) * * * * Return value: SUCCEED - aggregate item evaluated successfully * * FAIL - otherwise * * * ******************************************************************************/ static int evaluate_aggregate(DC_ITEM *item, AGENT_RESULT *res, int grp_func, const char *groups, const char *itemkey, int item_func, const char *param) { const char *__function_name = "evaluate_aggregate"; char *sql = NULL; size_t sql_alloc = 1024, sql_offset = 0; zbx_uint64_t itemid; zbx_vector_uint64_t itemids; DB_RESULT result; DB_ROW row; unsigned char value_type; history_value_t value; int num = 0, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() grp_func:%d groups:'%s' itemkey:'%s' item_func:%d param:'%s'", __function_name, grp_func, groups, itemkey, item_func, param); memset(&value, 0, sizeof(value)); zbx_vector_uint64_create(&itemids); aggregate_get_items(&itemids, groups, itemkey); if (0 == itemids.values_num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No items for key [%s] in group(s) [%s]", itemkey, groups)); goto clean; } sql = zbx_malloc(sql, sql_alloc); if (ZBX_DB_GET_HIST_VALUE == item_func) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select value_type,lastvalue" " from items" " where lastvalue is not null" " and value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { value_type = (unsigned char)atoi(row[0]); evaluate_one(item, &value, &num, grp_func, row[1], value_type); } DBfree_result(result); } else { int clock_from; unsigned int period; char **h_value; if (FAIL == is_uint_suffix(param, &period)) { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter")); goto clean; } clock_from = time(NULL) - period; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,value_type" " from items" " where value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); value_type = (unsigned char)atoi(row[1]); h_value = DBget_history(itemid, value_type, item_func, clock_from, 0, NULL, NULL, 0); if (NULL != h_value[0]) evaluate_one(item, &value, &num, grp_func, h_value[0], value_type); DBfree_history(h_value); } DBfree_result(result); } if (0 == num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key \"%s\" in group(s) \"%s\"", itemkey, groups)); goto clean; } if (ZBX_GRP_FUNC_AVG == grp_func) { switch (item->value_type) { case ITEM_VALUE_TYPE_FLOAT: value.dbl = value.dbl / num; break; case ITEM_VALUE_TYPE_UINT64: value.ui64 = value.ui64 / num; break; default: assert(0); } } if (ITEM_VALUE_TYPE_FLOAT == item->value_type) SET_DBL_RESULT(res, value.dbl); else SET_UI64_RESULT(res, value.ui64); ret = SUCCEED; clean: zbx_vector_uint64_destroy(&itemids); zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: evaluate_aggregate * * * * Parameters: grpfunc - grpavg, grpmax, grpmin, grpsum * * groups - list of comma-separated host groups * * itemkey - item key to aggregate * * itemfunc - avg, count, last, max, min, sum * * param - itemfunc parameter (optional) * * * * Return value: SUCCEED - aggregate item evaluated successfully * * FAIL - otherwise * * * ******************************************************************************/ static int evaluate_aggregate(AGENT_RESULT *res, const char *grpfunc, const char *groups, const char *itemkey, const char *itemfunc, const char *param) { const char *__function_name = "evaluate_aggregate"; char *sql = NULL; size_t sql_alloc = 1024, sql_offset = 0; zbx_uint64_t itemid, *ids = NULL; int ids_alloc = 0, ids_num = 0; DB_RESULT result; DB_ROW row; unsigned char value_type; double d = 0; int num = 0; int item_func, grp_func; int ret = FAIL; int grpany_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s() grpfunc:'%s' groups:'%s' itemkey:'%s' function:'%s(%s)'", __function_name, grpfunc, groups, itemkey, itemfunc, param); if (0 == strcmp(grpfunc, "grpmin")) grp_func = ZBX_GRP_FUNC_MIN; else if (0 == strcmp(grpfunc, "grpavg")) grp_func = ZBX_GRP_FUNC_AVG; else if (0 == strcmp(grpfunc, "grpmax")) grp_func = ZBX_GRP_FUNC_MAX; else if (0 == strcmp(grpfunc, "grpsum")) grp_func = ZBX_GRP_FUNC_SUM; else if (0 == strcmp(grpfunc, "grpany")) grp_func = ZBX_GRP_FUNC_ANY; else goto clean; if (0 == strcmp(itemfunc, "min")) item_func = ZBX_DB_GET_HIST_MIN; else if (0 == strcmp(itemfunc, "avg")) item_func = ZBX_DB_GET_HIST_AVG; else if (0 == strcmp(itemfunc, "max")) item_func = ZBX_DB_GET_HIST_MAX; else if (0 == strcmp(itemfunc, "sum")) item_func = ZBX_DB_GET_HIST_SUM; else if (0 == strcmp(itemfunc, "count")) item_func = ZBX_DB_GET_HIST_COUNT; else if (0 == strcmp(itemfunc, "last")) item_func = ZBX_DB_GET_HIST_VALUE; else { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid third parameter")); goto clean; } aggregate_get_items(&ids, &ids_alloc, &ids_num, groups, itemkey); if (0 == ids_num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No items for key [%s] in group(s) [%s]", itemkey, groups)); goto clean; } if (ZBX_GRP_FUNC_ANY == grp_func) { /* * * * Adding linked host-level itemids into historyitems * so it will insert the data into history for trigger * * Also disabled the grpany item(group level item) writting * We do not need to duplicate the values * As we changed the evalfunc and expression * to expand the group and eval the trigger value from history table directly * */ for (grpany_offset = 0; grpany_offset < ids_num ; ++grpany_offset) { itemid = ids[grpany_offset]; DCadd_historyitems(itemid); } SET_DBL_RESULT(res, 1); grp_func = ZBX_GRP_FUNC_ANY; ret = SUCCEED; goto clean; } sql = zbx_malloc(sql, sql_alloc); if (ZBX_DB_GET_HIST_VALUE == item_func) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select value_type,lastvalue" " from items" " where lastvalue is not null" " and value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", ids, ids_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { value_type = (unsigned char)atoi(row[0]); evaluate_one(&d, &num, grp_func, row[1], value_type); } DBfree_result(result); } else { int clock_from; unsigned int period; char **h_value; if (FAIL == is_uint_suffix(param, &period)) { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter")); goto clean; } clock_from = time(NULL) - period; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,value_type" " from items" " where value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", ids, ids_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); value_type = (unsigned char)atoi(row[1]); h_value = DBget_history(itemid, value_type, item_func, clock_from, 0, NULL, NULL, 0); if (NULL != h_value[0]) { evaluate_one(&d, &num, grp_func, h_value[0], value_type); } DBfree_history(h_value); } DBfree_result(result); } if (0 == num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key [%s] in group [%s]", itemkey, groups)); goto clean; } if (ZBX_GRP_FUNC_AVG == grp_func) d = d / num; SET_DBL_RESULT(res, d); zabbix_log(LOG_LEVEL_DEBUG, "%s() result:" ZBX_FS_DBL, __function_name, d); ret = SUCCEED; clean: zbx_free(ids); zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }