/******************************************************************************
 *                                                                            *
 * 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;
}
Exemple #2
0
/******************************************************************************
 *                                                                            *
 * 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;
}