Esempio n. 1
0
/******************************************************************************
 *                                                                            *
 * Function: process_values                                                   *
 *                                                                            *
 * Purpose: process new item values                                           *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev, Alexander Vladishev                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_values(icmpitem_t *items, int first_index, int last_index, ZBX_FPING_HOST *hosts,
		int hosts_count, zbx_timespec_t *ts, int ping_result, char *error)
{
	const char	*__function_name = "process_values";
	int		i, h;
	zbx_uint64_t	value_uint64;
	double		value_dbl;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	for (h = 0; h < hosts_count; h++)
	{
		if (NOTSUPPORTED == ping_result)
			zabbix_log(LOG_LEVEL_DEBUG, "Host [%s] %s",
					hosts[h].addr, error);
		else
			zabbix_log(LOG_LEVEL_DEBUG, "Host [%s] cnt=%d rcv=%d min/max/avg=" ZBX_FS_DBL "/" ZBX_FS_DBL "/" ZBX_FS_DBL,
					hosts[h].addr, hosts[h].cnt, hosts[h].rcv, hosts[h].min, hosts[h].max, hosts[h].avg);

		for (i = first_index; i < last_index; i++)
		{
			if (0 == strcmp(items[i].addr, hosts[h].addr))
			{
				switch (items[i].icmpping)
				{
					case ICMPPING:
						value_uint64 = hosts[h].rcv ? 1 : 0;
						process_value(items[i].itemid, &value_uint64, NULL, ts, ping_result, error);
						break;
					case ICMPPINGSEC:
						switch (items[i].type)
						{
							case ICMPPINGSEC_MIN:
								value_dbl = hosts[h].min;
								break;
							case ICMPPINGSEC_MAX:
								value_dbl = hosts[h].max;
								break;
							case ICMPPINGSEC_AVG:
								value_dbl = hosts[h].avg;
								break;
						}
						process_value(items[i].itemid, NULL, &value_dbl, ts, ping_result, error);
						break;
					case ICMPPINGLOSS:
						if (0 == hosts[h].cnt)
							value_dbl = 0;
						else
							value_dbl = 100 * (1 - (double)hosts[h].rcv / (double)hosts[h].cnt);
						process_value(items[i].itemid, NULL, &value_dbl, ts, ping_result, error);
						break;
				}
			}
		}
	}

	dc_flush_history();

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Esempio n. 2
0
/******************************************************************************
 *                                                                            *
 * Function: get_pinger_hosts                                                 *
 *                                                                            *
 * Purpose: creates buffer which contains list of hosts to ping               *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCEED - the file was created successfully                  *
 *               FAIL - otherwise                                             *
 *                                                                            *
 * Author: Alexei Vladishev, Alexander Vladishev                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	get_pinger_hosts(icmpitem_t **icmp_items, int *icmp_items_alloc, int *icmp_items_count)
{
	const char		*__function_name = "get_pinger_hosts";
	DC_ITEM			items[MAX_PINGER_ITEMS];
	int			i, num, count, interval, size, timeout, rc, errcode = SUCCEED;
	char			error[MAX_STRING_LEN], *addr = NULL;
	icmpping_t		icmpping;
	icmppingsec_type_t	type;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	num = DCconfig_get_poller_items(ZBX_POLLER_TYPE_PINGER, items);

	for (i = 0; i < num; i++)
	{
		ZBX_STRDUP(items[i].key, items[i].key_orig);
		rc = substitute_key_macros(&items[i].key, NULL, &items[i], NULL, MACRO_TYPE_ITEM_KEY,
				error, sizeof(error));

		if (SUCCEED == rc)
		{
			rc = parse_key_params(items[i].key, items[i].interface.addr, &icmpping, &addr, &count,
					&interval, &size, &timeout, &type, error, sizeof(error));
		}

		if (SUCCEED == rc)
		{
			add_icmpping_item(icmp_items, icmp_items_alloc, icmp_items_count, count, interval, size,
				timeout, items[i].itemid, addr, icmpping, type);
		}
		else
		{
			zbx_timespec_t	ts;

			zbx_timespec(&ts);

			items[i].state = ITEM_STATE_NOTSUPPORTED;
			dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL, &ts,
					items[i].state, error);

			DCrequeue_items(&items[i].itemid, &items[i].state, &ts.sec, NULL, NULL, &errcode, 1);
		}

		zbx_free(items[i].key);
	}

	DCconfig_clean_items(items, NULL, num);

	dc_flush_history();

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, *icmp_items_count);
}
Esempio n. 3
0
/******************************************************************************
 *                                                                            *
 * Function: process_trap_for_interface                                       *
 *                                                                            *
 * Purpose: add trap to all matching items for the specified interface        *
 *                                                                            *
 * Return value: SUCCEED - a matching item was found                          *
 *               FAIL - no matching item was found (including fallback items) *
 *                                                                            *
 * Author: Rudolfs Kreicbergs                                                 *
 *                                                                            *
 ******************************************************************************/
static int	process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_timespec_t *ts)
{
	DC_ITEM			*items = NULL;
	const char		*regex;
	char			error[ITEM_ERROR_LEN_MAX];
	size_t			num, i;
	int			ret = FAIL, fb = -1, *lastclocks = NULL, *errcodes = NULL;
	zbx_uint64_t		*itemids = NULL;
	unsigned char		*states = NULL;
	AGENT_RESULT		*results = NULL;
	AGENT_REQUEST		request;
	zbx_vector_ptr_t	regexps;

	zbx_vector_ptr_create(&regexps);

	num = DCconfig_get_snmp_items_by_interfaceid(interfaceid, &items);

	itemids = zbx_malloc(itemids, sizeof(zbx_uint64_t) * num);
	states = zbx_malloc(states, sizeof(unsigned char) * num);
	lastclocks = zbx_malloc(lastclocks, sizeof(int) * num);
	errcodes = zbx_malloc(errcodes, sizeof(int) * num);
	results = zbx_malloc(results, sizeof(AGENT_RESULT) * num);

	for (i = 0; i < num; i++)
	{
		init_result(&results[i]);
		errcodes[i] = FAIL;

		items[i].key = zbx_strdup(items[i].key, items[i].key_orig);
		if (SUCCEED != substitute_key_macros(&items[i].key, NULL, &items[i], NULL,
				MACRO_TYPE_ITEM_KEY, error, sizeof(error)))
		{
			SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error));
			errcodes[i] = NOTSUPPORTED;
			continue;
		}

		if (0 == strcmp(items[i].key, "snmptrap.fallback"))
		{
			fb = i;
			continue;
		}

		init_request(&request);

		if (SUCCEED != parse_item_key(items[i].key, &request))
			goto next;

		if (0 != strcmp(get_rkey(&request), "snmptrap"))
			goto next;

		if (1 < get_rparams_num(&request))
			goto next;

		if (NULL != (regex = get_rparam(&request, 0)))
		{
			if ('@' == *regex)
			{
				DCget_expressions_by_name(&regexps, regex + 1);

				if (0 == regexps.values_num)
				{
					SET_MSG_RESULT(&results[i], zbx_dsprintf(NULL,
							"Global regular expression \"%s\" does not exist.", regex + 1));
					errcodes[i] = NOTSUPPORTED;
					goto next;
				}
			}

			if (SUCCEED != regexp_match_ex(&regexps, trap, regex, ZBX_CASE_SENSITIVE))
				goto next;
		}

		if (SUCCEED == set_result_type(&results[i], items[i].value_type, items[i].data_type, trap))
			errcodes[i] = SUCCEED;
		else
			errcodes[i] = NOTSUPPORTED;
		ret = SUCCEED;
next:
		free_request(&request);
	}

	if (FAIL == ret && -1 != fb)
	{
		if (SUCCEED == set_result_type(&results[fb], items[fb].value_type, items[fb].data_type, trap))
			errcodes[fb] = SUCCEED;
		else
			errcodes[fb] = NOTSUPPORTED;
		ret = SUCCEED;
	}

	for (i = 0; i < num; i++)
	{
		switch (errcodes[i])
		{
			case SUCCEED:
				if (ITEM_VALUE_TYPE_LOG == items[i].value_type)
				{
					calc_timestamp(results[i].log->value, &results[i].log->timestamp,
							items[i].logtimefmt);
				}

				items[i].state = ITEM_STATE_NORMAL;
				dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, &results[i],
						ts, items[i].state, NULL);

				itemids[i] = items[i].itemid;
				states[i] = items[i].state;
				lastclocks[i] = ts->sec;
				break;
			case NOTSUPPORTED:
				items[i].state = ITEM_STATE_NOTSUPPORTED;
				dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL,
						ts, items[i].state, results[i].msg);

				itemids[i] = items[i].itemid;
				states[i] = items[i].state;
				lastclocks[i] = ts->sec;
				break;
		}

		zbx_free(items[i].key);
		free_result(&results[i]);
	}

	zbx_free(results);

	DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num);

	zbx_free(errcodes);
	zbx_free(lastclocks);
	zbx_free(states);
	zbx_free(itemids);

	DCconfig_clean_items(items, NULL, num);
	zbx_free(items);

	zbx_regexp_clean_expressions(&regexps);
	zbx_vector_ptr_destroy(&regexps);

	dc_flush_history();

	return ret;
}
Esempio n. 4
0
/******************************************************************************
 *                                                                            *
 * Function: process_httptest                                                 *
 *                                                                            *
 * Purpose: process single scenario of http test                              *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_httptest(DC_HOST *host, zbx_httptest_t *httptest)
{
    const char	*__function_name = "process_httptest";

    DB_RESULT	result;
    DB_ROW		row;
    DB_HTTPSTEP	httpstep;
    char		*err_str = NULL;
    int		lastfailedstep;
    zbx_timespec_t	ts;
    zbx_httpstat_t	stat;
    double		speed_download = 0;
    int		speed_download_num = 0;
#ifdef HAVE_LIBCURL
    int		err;
    char		auth[HTTPTEST_HTTP_USER_LEN_MAX + HTTPTEST_HTTP_PASSWORD_LEN_MAX];
    CURL            *easyhandle = NULL;
#endif

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() httptestid:" ZBX_FS_UI64 " name:'%s'",
               __function_name, httptest->httptest.httptestid, httptest->httptest.name);

    lastfailedstep = 0;

    result = DBselect(
                 "select httpstepid,no,name,url,timeout,posts,required,status_codes,variables"
                 " from httpstep"
                 " where httptestid=" ZBX_FS_UI64
                 " order by no",
                 httptest->httptest.httptestid);

#ifdef HAVE_LIBCURL
    if (NULL == (easyhandle = curl_easy_init()))
    {
        err_str = zbx_strdup(err_str, "cannot initialize cURL library");
        goto clean;
    }

    if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_PROXY, httptest->httptest.http_proxy)) ||
            CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_COOKIEFILE, "")) ||
            CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, httptest->httptest.agent)) ||
            CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 1L)) ||
            CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, WRITEFUNCTION2)) ||
            CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, HEADERFUNCTION2)) ||
            CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, 0L)) ||
            CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, 0L)))
    {
        err_str = zbx_strdup(err_str, curl_easy_strerror(err));
        goto clean;
    }

    while (NULL != (row = DBfetch(result)))
    {
        /* NOTE: do not break or return from this block! */
        /*       process_step_data() call is required! */

        ZBX_STR2UINT64(httpstep.httpstepid, row[0]);
        httpstep.httptestid = httptest->httptest.httptestid;
        httpstep.no = atoi(row[1]);
        httpstep.name = row[2];

        httpstep.url = zbx_strdup(NULL, row[3]);
        substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, host, NULL,
                                 &httpstep.url, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0);

        httpstep.timeout = atoi(row[4]);

        httpstep.posts = zbx_strdup(NULL, row[5]);
        substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, host, NULL,
                                 &httpstep.posts, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0);

        httpstep.required = zbx_strdup(NULL, row[6]);
        substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, host, NULL,
                                 &httpstep.required, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0);

        httpstep.status_codes = zbx_strdup(NULL, row[7]);
        substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL,
                                 &httpstep.status_codes, MACRO_TYPE_COMMON, NULL, 0);

        httpstep.variables = row[8];

        memset(&stat, 0, sizeof(stat));

        http_substitute_variables(httptest, &httpstep.url);
        http_substitute_variables(httptest, &httpstep.posts);

        zabbix_log(LOG_LEVEL_DEBUG, "%s() use step \"%s\"", __function_name, httpstep.name);

        if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, httpstep.posts)))
        {
            err_str = zbx_strdup(err_str, curl_easy_strerror(err));
            goto httpstep_error;
        }

        if ('\0' != *httpstep.posts)
            zabbix_log(LOG_LEVEL_DEBUG, "%s() use post \"%s\"", __function_name, httpstep.posts);

        if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_POST, '\0' != *httpstep.posts ? 1L : 0L)))
        {
            err_str = zbx_strdup(err_str, curl_easy_strerror(err));
            goto httpstep_error;
        }

        if (HTTPTEST_AUTH_NONE != httptest->httptest.authentication)
        {
            long	curlauth = 0;

            zabbix_log(LOG_LEVEL_DEBUG, "%s() setting HTTPAUTH [%d]",
                       __function_name, httptest->httptest.authentication);
            zabbix_log(LOG_LEVEL_DEBUG, "%s() setting USERPWD for authentication", __function_name);

            switch (httptest->httptest.authentication)
            {
            case HTTPTEST_AUTH_BASIC:
                curlauth = CURLAUTH_BASIC;
                break;
            case HTTPTEST_AUTH_NTLM:
                curlauth = CURLAUTH_NTLM;
                break;
            default:
                THIS_SHOULD_NEVER_HAPPEN;
                break;
            }

            zbx_snprintf(auth, sizeof(auth), "%s:%s", httptest->httptest.http_user,
                         httptest->httptest.http_password);

            if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, curlauth)) ||
                    CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_USERPWD, auth)))
            {
                err_str = zbx_strdup(err_str, curl_easy_strerror(err));
                goto httpstep_error;
            }
        }

        zabbix_log(LOG_LEVEL_DEBUG, "%s() go to URL \"%s\"", __function_name, httpstep.url);

        if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_TIMEOUT, (long)httpstep.timeout)) ||
                CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_URL, httpstep.url)))
        {
            err_str = zbx_strdup(err_str, curl_easy_strerror(err));
            goto httpstep_error;
        }

        /* try to retrieve page several times depending on number of retries */
        do
        {
            memset(&page, 0, sizeof(page));

            if (CURLE_OK == (err = curl_easy_perform(easyhandle)))
                break;
        }
        while (0 != --httptest->httptest.retries);

        if (CURLE_OK == err)
        {
            char	*var_err_str = NULL;

            /* first get the data that is needed even if step fails */
            if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_RESPONSE_CODE, &stat.rspcode)))
            {
                err_str = zbx_strdup(err_str, curl_easy_strerror(err));
            }
            else if ('\0' != *httpstep.status_codes &&
                     FAIL == int_in_list(httpstep.status_codes, stat.rspcode))
            {
                err_str = zbx_strdup(err_str, "status code did not match");
            }

            if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_TOTAL_TIME, &stat.total_time)) &&
                    NULL == err_str)
            {
                err_str = zbx_strdup(err_str, curl_easy_strerror(err));
            }

            if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_SPEED_DOWNLOAD,
                                   &stat.speed_download)) && NULL == err_str)
            {
                err_str = zbx_strdup(err_str, curl_easy_strerror(err));
            }
            else
            {
                speed_download += stat.speed_download;
                speed_download_num++;
            }

            /* required pattern */
            if (NULL == err_str && '\0' != *httpstep.required && NULL == zbx_regexp_match(page.data,
                    httpstep.required, NULL))
            {
                err_str = zbx_strdup(err_str, "required pattern not found");
            }

            /* variables defined in scenario */
            if (NULL == err_str && FAIL == http_process_variables(httptest, httptest->httptest.variables,
                    page.data, &var_err_str))
            {
                char	*variables;

                variables = string_replace(httptest->httptest.variables, "\r\n", " ");
                err_str = zbx_dsprintf(err_str, "error in scenario variables \"%s\": %s",
                                       variables, var_err_str);
                zbx_free(variables);
            }

            /* variables defined in a step */
            if (NULL == err_str && FAIL == http_process_variables(httptest, httpstep.variables, page.data,
                    &var_err_str))
            {
                char	*variables;

                variables = string_replace(httpstep.variables, "\r\n", " ");
                err_str = zbx_dsprintf(err_str, "error in step variables \"%s\": %s",
                                       variables, var_err_str);
                zbx_free(variables);
            }

            zbx_free(var_err_str);
        }
        else
            err_str = zbx_strdup(err_str, curl_easy_strerror(err));

        zbx_free(page.data);
httpstep_error:
        zbx_free(httpstep.status_codes);
        zbx_free(httpstep.required);
        zbx_free(httpstep.posts);
        zbx_free(httpstep.url);

        zbx_timespec(&ts);
        process_step_data(httpstep.httpstepid, &stat, &ts);

        if (NULL != err_str)
        {
            lastfailedstep = httpstep.no;
            break;
        }
    }
clean:
    curl_easy_cleanup(easyhandle);
#else
    err_str = zbx_strdup(err_str, "cURL library is required for Web monitoring support");
#endif	/* HAVE_LIBCURL */

    zbx_timespec(&ts);

    if (NULL != err_str)
    {
        if (0 == lastfailedstep)
        {
            /* we are here either because cURL initialization failed */
            /* or we have been compiled without cURL library */

            lastfailedstep = 1;

            if (NULL != (row = DBfetch(result)))
            {
                ZBX_STR2UINT64(httpstep.httpstepid, row[0]);
                httpstep.name = row[2];

                memset(&stat, 0, sizeof(stat));

                process_step_data(httpstep.httpstepid, &stat, &ts);
            }
            else
                THIS_SHOULD_NEVER_HAPPEN;
        }

        zabbix_log(LOG_LEVEL_WARNING, "cannot process step \"%s\" of web scenario \"%s\" on host \"%s\": %s",
                   httpstep.name, httptest->httptest.name, host->name, err_str);
    }
    DBfree_result(result);

    DBexecute("update httptest set nextcheck=%d+delay where httptestid=" ZBX_FS_UI64,
              ts.sec, httptest->httptest.httptestid);

    if (0 != speed_download_num)
        speed_download /= speed_download_num;

    process_test_data(httptest->httptest.httptestid, lastfailedstep, speed_download, err_str, &ts);

    zbx_free(err_str);

    dc_flush_history();

    zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Esempio n. 5
0
/******************************************************************************
 *                                                                            *
 * Function: process_values                                                   *
 *                                                                            *
 * Purpose: process new item values                                           *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev, Alexander Vladishev                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_values(icmpitem_t *items, int first_index, int last_index, ZBX_FPING_HOST *hosts,
		int hosts_count, zbx_timespec_t *ts, int ping_result, char *error)
{
	const char	*__function_name = "process_values";
	int		i, h;
	zbx_uint64_t	value_uint64;
	double		value_dbl;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	for (h = 0; h < hosts_count; h++)
	{
		const ZBX_FPING_HOST	*host = &hosts[h];

		if (NOTSUPPORTED == ping_result)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "host [%s] %s", host->addr, error);
		}
		else
		{
			zabbix_log(LOG_LEVEL_DEBUG, "host [%s] cnt=%d rcv=%d"
					" min=" ZBX_FS_DBL " max=" ZBX_FS_DBL " sum=" ZBX_FS_DBL,
					host->addr, host->cnt, host->rcv, host->min, host->max, host->sum);
		}

		for (i = first_index; i < last_index; i++)
		{
			const icmpitem_t	*item = &items[i];

			if (0 != strcmp(item->addr, host->addr))
				continue;

			if (NOTSUPPORTED == ping_result)
			{
				process_value(item->itemid, NULL, NULL, ts, NOTSUPPORTED, error);
				continue;
			}

			if (0 == host->cnt)
			{
				process_value(item->itemid, NULL, NULL, ts, NOTSUPPORTED,
						"Cannot send ICMP ping packets to this host.");
				continue;
			}

			switch (item->icmpping)
			{
				case ICMPPING:
					value_uint64 = (0 != host->rcv ? 1 : 0);
					process_value(item->itemid, &value_uint64, NULL, ts, SUCCEED, NULL);
					break;
				case ICMPPINGSEC:
					switch (item->type)
					{
						case ICMPPINGSEC_MIN:
							value_dbl = host->min;
							break;
						case ICMPPINGSEC_MAX:
							value_dbl = host->max;
							break;
						case ICMPPINGSEC_AVG:
							value_dbl = (0 != host->rcv ? host->sum / host->rcv : 0);
							break;
					}
					process_value(item->itemid, NULL, &value_dbl, ts, SUCCEED, NULL);
					break;
				case ICMPPINGLOSS:
					value_dbl = (100 * (host->cnt - host->rcv)) / (double)host->cnt;
					process_value(item->itemid, NULL, &value_dbl, ts, SUCCEED, NULL);
					break;
			}
		}
	}

	dc_flush_history();

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}