/******************************************************************************
 *                                                                            *
 * 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;
}
Beispiel #2
0
/******************************************************************************
 *                                                                            *
 * Function: get_value_internal                                               *
 *                                                                            *
 * Purpose: retrieve data from Zabbix server (internally supported items)     *
 *                                                                            *
 * Parameters: item - item we are interested in                               *
 *                                                                            *
 * Return value: SUCCEED - data successfully retrieved and stored in result   *
 *               NOTSUPPORTED - requested item is not supported               *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
int	get_value_internal(DC_ITEM *item, AGENT_RESULT *result)
{
    int		nparams;
    char		params[MAX_STRING_LEN], *error = NULL;
    char		tmp[MAX_STRING_LEN], tmp1[HOST_HOST_LEN_MAX];

    init_result(result);

    if (0 != strncmp(item->key, "zabbix[", 7))
        goto notsupported;

    if (2 != parse_command(item->key, NULL, 0, params, sizeof(params)))
        goto notsupported;

    if (0 != get_param(params, 1, tmp, sizeof(tmp)))
        goto notsupported;

    nparams = num_param(params);

    if (0 == strcmp(tmp, "triggers"))			/* zabbix["triggers"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_UI64_RESULT(result, DBget_row_count("triggers"));
    }
    else if (0 == strcmp(tmp, "items"))			/* zabbix["items"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_UI64_RESULT(result, DBget_row_count("items"));
    }
    else if (0 == strcmp(tmp, "items_unsupported"))		/* zabbix["items_unsupported"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_UI64_RESULT(result, DBget_items_unsupported_count());
    }
    else if (0 == strcmp(tmp, "history") ||			/* zabbix["history"] */
             0 == strcmp(tmp, "history_log") ||	/* zabbix["history_log"] */
             0 == strcmp(tmp, "history_str") ||	/* zabbix["history_str"] */
             0 == strcmp(tmp, "history_text") ||	/* zabbix["history_text"] */
             0 == strcmp(tmp, "history_uint"))	/* zabbix["history_uint"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_UI64_RESULT(result, DBget_row_count(tmp));
    }
    else if (0 == strcmp(tmp, "trends") ||			/* zabbix["trends"] */
             0 == strcmp(tmp, "trends_uint"))	/* zabbix["trends_uint"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_UI64_RESULT(result, DBget_row_count(tmp));
    }
    else if (0 == strcmp(tmp, "queue"))			/* zabbix["queue",<from>,<to>] */
    {
        unsigned int	from = 6, to = (unsigned int)-1;

        if (3 < nparams)
        {
            error = zbx_strdup(error, "Invalid number of parameters");
            goto notsupported;
        }

        if (2 <= nparams)
        {
            if (0 != get_param(params, 2, tmp, sizeof(tmp)))
                goto notsupported;

            if ('\0' != *tmp && FAIL == is_uint_suffix(tmp, &from))
            {
                error = zbx_strdup(error, "Invalid second parameter");
                goto notsupported;
            }
        }

        if (3 <= nparams)
        {
            if (0 != get_param(params, 3, tmp, sizeof(tmp)))
                goto notsupported;

            if ('\0' != *tmp && FAIL == is_uint_suffix(tmp, &to))
            {
                error = zbx_strdup(error, "Invalid third parameter");
                goto notsupported;
            }
        }

        if ((unsigned int)-1 != to && from > to)
        {
            error = zbx_strdup(error, "Parameters represent an invalid interval");
            goto notsupported;
        }

        SET_UI64_RESULT(result, DBget_queue_count((int)from, (int)to));
    }
    else if (0 == strcmp(tmp, "requiredperformance"))	/* zabbix["requiredperformance"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_DBL_RESULT(result, DBget_requiredperformance());
    }
    else if (0 == strcmp(tmp, "uptime"))			/* zabbix["uptime"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_UI64_RESULT(result, time(NULL) - CONFIG_SERVER_STARTUP_TIME);
    }
    else if (0 == strcmp(tmp, "boottime"))			/* zabbix["boottime"] */
    {
        if (1 != nparams)
            goto notsupported;

        SET_UI64_RESULT(result, CONFIG_SERVER_STARTUP_TIME);
    }
    else if (0 == strcmp(tmp, "host"))			/* zabbix["host",<type>,"available"] */
    {
        if (3 != nparams)
            goto notsupported;

        if (0 != get_param(params, 3, tmp, sizeof(tmp)) || 0 != strcmp(tmp, "available"))
            goto notsupported;

        if (0 != get_param(params, 2, tmp, sizeof(tmp)))
            goto notsupported;

        if (0 == strcmp(tmp, "agent"))
            SET_UI64_RESULT(result, item->host.available);
        else if (0 == strcmp(tmp, "snmp"))
            SET_UI64_RESULT(result, item->host.snmp_available);
        else if (0 == strcmp(tmp, "ipmi"))
            SET_UI64_RESULT(result, item->host.ipmi_available);
        else if (0 == strcmp(tmp, "jmx"))
            SET_UI64_RESULT(result, item->host.jmx_available);
        else
            goto notsupported;

        result->ui64 = 2 - result->ui64;
    }
    else if (0 == strcmp(tmp, "proxy"))			/* zabbix["proxy",<hostname>,"lastaccess"] */
    {
        int	lastaccess;

        if (3 != nparams)
            goto notsupported;

        if (0 != get_param(params, 2, tmp1, sizeof(tmp1)))
            goto notsupported;

        if (0 != get_param(params, 3, tmp, sizeof(tmp)) || 0 != strcmp(tmp, "lastaccess"))
            goto notsupported;

        if (FAIL == DBget_proxy_lastaccess(tmp1, &lastaccess, &error))
            goto notsupported;

        SET_UI64_RESULT(result, lastaccess);
    }
    else if (0 == strcmp(tmp, "java"))			/* zabbix["java",...] */
    {
        int	res;

        alarm(CONFIG_TIMEOUT);
        res = get_value_java(ZBX_JAVA_GATEWAY_REQUEST_INTERNAL, item, result);
        alarm(0);

        if (SUCCEED != res)
            goto notsupported;
    }
    else if (0 == strcmp(tmp, "process"))			/* zabbix["process",<type>,<mode>,<state>] */
    {
        unsigned char	process_type;
        int		process_forks;
        double		value;

        if (4 < nparams)
        {
            error = zbx_strdup(error, "Invalid number of parameters");
            goto notsupported;
        }

        if (0 != get_param(params, 2, tmp, sizeof(tmp)))
        {
            error = zbx_strdup(error, "Required second parameter missing");
            goto notsupported;
        }

        for (process_type = 0; process_type < ZBX_PROCESS_TYPE_COUNT; process_type++)
            if (0 == strcmp(tmp, get_process_type_string(process_type)))
                break;

        if (ZBX_PROCESS_TYPE_COUNT == process_type)
        {
            error = zbx_strdup(error, "Invalid second parameter");
            goto notsupported;
        }

        process_forks = get_process_type_forks(process_type);

        if (0 != get_param(params, 3, tmp, sizeof(tmp)))
            *tmp = '\0';

        if (0 == strcmp(tmp, "count"))
        {
            if (3 < nparams)
            {
                error = zbx_strdup(error, "Invalid number of parameters");
                goto notsupported;
            }

            SET_UI64_RESULT(result, process_forks);
        }
        else
        {
            unsigned char	aggr_func, state;
            unsigned short	process_num = 0;

            if ('\0' == *tmp || 0 == strcmp(tmp, "avg"))
                aggr_func = ZBX_AGGR_FUNC_AVG;
            else if (0 == strcmp(tmp, "max"))
                aggr_func = ZBX_AGGR_FUNC_MAX;
            else if (0 == strcmp(tmp, "min"))
                aggr_func = ZBX_AGGR_FUNC_MIN;
            else if (SUCCEED == is_ushort(tmp, &process_num) && 0 < process_num)
                aggr_func = ZBX_AGGR_FUNC_ONE;
            else
            {
                error = zbx_strdup(error, "Invalid third parameter");
                goto notsupported;
            }

            if (0 == process_forks)
            {
                error = zbx_dsprintf(error, "No \"%s\" processes started",
                                     get_process_type_string(process_type));
                goto notsupported;
            }
            else if (process_num > process_forks)
            {
                error = zbx_dsprintf(error, "\"%s\" #%d is not started",
                                     get_process_type_string(process_type), process_num);
                goto notsupported;
            }

            if (0 != get_param(params, 4, tmp, sizeof(tmp)))
                *tmp = '\0';

            if ('\0' == *tmp || 0 == strcmp(tmp, "busy"))
                state = ZBX_PROCESS_STATE_BUSY;
            else if (0 == strcmp(tmp, "idle"))
                state = ZBX_PROCESS_STATE_IDLE;
            else
            {
                error = zbx_strdup(error, "Invalid fourth parameter");
                goto notsupported;
            }

            get_selfmon_stats(process_type, aggr_func, process_num, state, &value);

            SET_DBL_RESULT(result, value);
        }
    }
    else if (0 == strcmp(tmp, "wcache"))			/* zabbix[wcache,<cache>,<mode>] */
    {
        if (3 < nparams)
            goto notsupported;

        if (0 != get_param(params, 2, tmp, sizeof(tmp)))
            goto notsupported;

        if (0 != get_param(params, 3, tmp1, sizeof(tmp1)))
            *tmp1 = '\0';

        if (0 == strcmp(tmp, "values"))
        {
            if ('\0' == *tmp1 || 0 == strcmp(tmp1, "all"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_COUNTER));
            else if (0 == strcmp(tmp1, "float"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FLOAT_COUNTER));
            else if (0 == strcmp(tmp1, "uint"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_UINT_COUNTER));
            else if (0 == strcmp(tmp1, "str"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_STR_COUNTER));
            else if (0 == strcmp(tmp1, "log"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_LOG_COUNTER));
            else if (0 == strcmp(tmp1, "text"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TEXT_COUNTER));
            else if (0 == strcmp(tmp1, "not supported"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_NOTSUPPORTED_COUNTER));
            else
                goto notsupported;
        }
        else if (0 == strcmp(tmp, "history"))
        {
            if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
                SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_PFREE));
            else if (0 == strcmp(tmp1, "total"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TOTAL));
            else if (0 == strcmp(tmp1, "used"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_USED));
            else if (0 == strcmp(tmp1, "free"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FREE));
            else
                goto notsupported;
        }
        else if (0 == strcmp(tmp, "trend"))
        {
            if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
                SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TREND_PFREE));
            else if (0 == strcmp(tmp1, "total"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_TOTAL));
            else if (0 == strcmp(tmp1, "used"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_USED));
            else if (0 == strcmp(tmp1, "free"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_FREE));
            else
                goto notsupported;
        }
        else if (0 == strcmp(tmp, "text"))
        {
            if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
                SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TEXT_PFREE));
            else if (0 == strcmp(tmp1, "total"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TEXT_TOTAL));
            else if (0 == strcmp(tmp1, "used"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TEXT_USED));
            else if (0 == strcmp(tmp1, "free"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TEXT_FREE));
            else
                goto notsupported;
        }
        else
            goto notsupported;
    }
    else if (0 == strcmp(tmp, "rcache"))			/* zabbix[rcache,<cache>,<mode>] */
    {
        if (3 < nparams)
            goto notsupported;

        if (0 != get_param(params, 2, tmp, sizeof(tmp)))
            goto notsupported;

        if (0 != get_param(params, 3, tmp1, sizeof(tmp1)))
            *tmp1 = '\0';

        if (0 == strcmp(tmp, "buffer"))
        {
            if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
                SET_DBL_RESULT(result, *(double *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_PFREE));
            else if (0 == strcmp(tmp1, "total"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_TOTAL));
            else if (0 == strcmp(tmp1, "used"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_USED));
            else if (0 == strcmp(tmp1, "free"))
                SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_FREE));
            else
                goto notsupported;
        }
        else
            goto notsupported;
    }
    else
        goto notsupported;

    return SUCCEED;
notsupported:
    if (!ISSET_MSG(result))
    {
        if (NULL == error)
            error = zbx_strdup(error, "Internal check is not supported");

        SET_MSG_RESULT(result, error);
    }

    return NOTSUPPORTED;
}
/******************************************************************************
 *                                                                            *
 * 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_VALUE_FUNC_*                       *
 *             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";
	zbx_vector_uint64_t		itemids;
	history_value_t			value, item_result;
	zbx_history_record_t		group_value;
	int				ret = FAIL, now, *errcodes = NULL, i, count;
	DC_ITEM				*items = NULL;
	zbx_vector_history_record_t	values, group_values;
	unsigned int			seconds;

	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, ZBX_NULL2STR(param));

	now = time(NULL);

	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 clean1;
	}

	memset(&value, 0, sizeof(value));
	zbx_history_record_vector_create(&group_values);

	items = zbx_malloc(items, sizeof(DC_ITEM) * itemids.values_num);
	errcodes = zbx_malloc(errcodes, sizeof(int) * itemids.values_num);

	DCconfig_get_items_by_itemids(items, itemids.values, errcodes, itemids.values_num);

	if (ZBX_VALUE_FUNC_LAST == item_func)
	{
		count = 1;
		seconds = 0;
	}
	else
	{
		if (FAIL == is_uint_suffix(param, &seconds))
		{
			SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter."));
			goto clean2;
		}
		count = 0;
	}

	for (i = 0; i < itemids.values_num; i++)
	{
		if (SUCCEED != errcodes[i])
			continue;

		if (ITEM_STATUS_ACTIVE != items[i].status)
			continue;

		if (HOST_STATUS_MONITORED != items[i].host.status)
			continue;

		if (ITEM_VALUE_TYPE_FLOAT != items[i].value_type && ITEM_VALUE_TYPE_UINT64 != items[i].value_type)
			continue;

		zbx_history_record_vector_create(&values);

		if (SUCCEED == zbx_vc_get_value_range(items[i].itemid, items[i].value_type, &values, seconds,
				count, now) && 0 < values.values_num)
		{
			evaluate_history_func(&values, items[i].value_type, item_func, &item_result);

			if (item->value_type == items[i].value_type)
				group_value.value = item_result;
			else
			{
				if (ITEM_VALUE_TYPE_UINT64 == item->value_type)
					group_value.value.ui64 = (zbx_uint64_t)item_result.dbl;
				else
					group_value.value.dbl = (double)item_result.ui64;
			}

			zbx_vector_history_record_append_ptr(&group_values, &group_value);
		}

		zbx_history_record_vector_destroy(&values, items[i].value_type);
	}

	if (0 == group_values.values_num)
	{
		SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key \"%s\" in group(s) \"%s\"", itemkey, groups));
		goto clean2;
	}

	evaluate_history_func(&group_values, item->value_type, grp_func, &value);

	if (ITEM_VALUE_TYPE_FLOAT == item->value_type)
		SET_DBL_RESULT(res, value.dbl);
	else
		SET_UI64_RESULT(res, value.ui64);

	ret = SUCCEED;
clean2:
	DCconfig_clean_items(items, errcodes, itemids.values_num);

	zbx_free(errcodes);
	zbx_free(items);
	zbx_history_record_vector_destroy(&group_values, item->value_type);
clean1:
	zbx_vector_uint64_destroy(&itemids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Beispiel #4
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;
}