예제 #1
0
/******************************************************************************
 *                                                                            *
 * Function: select_discovered_host                                           *
 *                                                                            *
 * Purpose: select hostid of discovered host                                  *
 *                                                                            *
 * Parameters: dhostid - discovered host id                                   *
 *                                                                            *
 * Return value: hostid - existing hostid, 0 - if not found                   *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static zbx_uint64_t	select_discovered_host(const DB_EVENT *event)
{
	const char	*__function_name = "select_discovered_host";
	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	hostid = 0;
	char		*sql = NULL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64,
			__function_name, event->eventid);

	switch (event->object)
	{
		case EVENT_OBJECT_DHOST:
			sql = zbx_dsprintf(sql,
				"select h.hostid"
				" from hosts h,interface i,dservices ds,dchecks dc,drules dr"
				" where h.hostid=i.hostid"
					" and i.ip=ds.ip"
					" and ds.dcheckid=dc.dcheckid"
					" and dc.druleid=dr.druleid"
					" and " ZBX_SQL_NULLCMP("dr.proxy_hostid", "h.proxy_hostid")
					" and i.useip=1"
					" and ds.dhostid=" ZBX_FS_UI64
					ZBX_SQL_NODE
				" order by i.hostid",
				event->objectid, DBand_node_local("i.interfaceid"));
			break;
		case EVENT_OBJECT_DSERVICE:
			sql = zbx_dsprintf(sql,
				"select h.hostid"
				" from hosts h,interface i,dservices ds,dchecks dc,drules dr"
				" where h.hostid=i.hostid"
					" and i.ip=ds.ip"
					" and ds.dcheckid=dc.dcheckid"
					" and dc.druleid=dr.druleid"
					" and " ZBX_SQL_NULLCMP("dr.proxy_hostid", "h.proxy_hostid")
					" and i.useip=1"
					" and ds.dserviceid =" ZBX_FS_UI64
					ZBX_SQL_NODE
				" order by i.hostid",
				event->objectid, DBand_node_local("i.interfaceid"));
			break;
		default:
			goto exit;
	}

	result = DBselectN(sql, 1);

	zbx_free(sql);

	if (NULL != (row = DBfetch(result)))
		ZBX_STR2UINT64(hostid, row[0]);
	DBfree_result(result);
exit:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():" ZBX_FS_UI64, __function_name, hostid);

	return hostid;
}
예제 #2
0
/******************************************************************************
 *                                                                            *
 * Function: op_groups_del                                                    *
 *                                                                            *
 * Purpose: delete groups from discovered host                                *
 *                                                                            *
 * Parameters: event    - [IN] event data                                     *
 *             groupids - [IN] IDs of groups to delete                        *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
void	op_groups_del(const DB_EVENT *event, zbx_vector_uint64_t *groupids)
{
	const char	*__function_name = "op_groups_del";

	DB_RESULT	result;
	zbx_uint64_t	hostid;
	char		*sql = NULL;
	size_t		sql_alloc = 256, sql_offset = 0;

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

	if (event->source != EVENT_SOURCE_DISCOVERY)
		return;

	if (event->object != EVENT_OBJECT_DHOST && event->object != EVENT_OBJECT_DSERVICE)
		return;

	if (0 == (hostid = select_discovered_host(event)))
		return;

	sql = zbx_malloc(sql, sql_alloc);

	/* make sure host belongs to at least one hostgroup */
	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select groupid"
			" from hosts_groups"
			" where hostid=" ZBX_FS_UI64
				" and not",
			hostid);
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "groupid", groupids->values, groupids->values_num);

	result = DBselectN(sql, 1);

	if (NULL == DBfetch(result))
	{
		zabbix_log(LOG_LEVEL_WARNING, "cannot remove host \"%s\" from all host groups:"
				" it must belong to at least one", zbx_host_string(hostid));
	}
	else
	{
		sql_offset = 0;
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				"delete from hosts_groups"
				" where hostid=" ZBX_FS_UI64
					" and",
				hostid);
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "groupid", groupids->values, groupids->values_num);

		DBexecute("%s", sql);
	}
	DBfree_result(result);

	zbx_free(sql);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
예제 #3
0
/******************************************************************************
 *                                                                            *
 * Function: select hostid of discovered host                                 *
 *                                                                            *
 * Purpose: select discovered host                                            *
 *                                                                            *
 * Parameters: dhostid - discovered host id                                   *
 *                                                                            *
 * Return value: hostid - existing hostid, 0 - if not found                   *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static zbx_uint64_t	select_discovered_host(DB_EVENT *event)
{
	const char	*__function_name = "select_discovered_host";
	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	hostid = 0;
	char		sql[512];

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64,
			__function_name, event->eventid);

	switch (event->object)
	{
		case EVENT_OBJECT_DHOST:
			zbx_snprintf(sql, sizeof(sql),
					"select h.hostid"
					" from hosts h,dservices ds"
					" where ds.ip=h.ip"
						" and ds.dhostid=" ZBX_FS_UI64
						DB_NODE
					" order by h.hostid",
					event->objectid, DBnode_local("h.hostid"));
			break;
		case EVENT_OBJECT_DSERVICE:
			zbx_snprintf(sql, sizeof(sql),
					"select h.hostid"
					" from hosts h,dservices ds"
					" where ds.ip=h.ip"
						" and ds.dserviceid=" ZBX_FS_UI64
						DB_NODE
					" order by h.hostid",
					event->objectid, DBnode_local("h.hostid"));
			break;
		default:
			goto exit;
	}

	result = DBselectN(sql, 1);

	if (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(hostid, row[0]);
	}
	DBfree_result(result);
exit:
	zabbix_log(LOG_LEVEL_DEBUG, "End %s():" ZBX_FS_UI64, __function_name, hostid);

	return hostid;
}
예제 #4
0
/******************************************************************************
 *                                                                            *
 * Function: discovery_separate_host                                          *
 *                                                                            *
 * Purpose: separate multiple-IP hosts                                        *
 *                                                                            *
 * Parameters: host ip address                                                *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static void	discovery_separate_host(DB_DRULE *drule, DB_DHOST *dhost, const char *ip)
{
	const char	*__function_name = "discovery_separate_host";

	DB_RESULT	result;
	DB_ROW		row;
	char		*ip_esc, *sql = NULL;
	zbx_uint64_t	dhostid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() ip:'%s'", __function_name, ip);

	ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN);
	sql = zbx_dsprintf(sql,
			"select dserviceid"
			" from dservices"
			" where dhostid=" ZBX_FS_UI64
				" and ip" ZBX_SQL_STRCMP,
			dhost->dhostid, ZBX_SQL_STRVAL_NE(ip_esc));

	result = DBselectN(sql, 1);

	if (NULL != (row = DBfetch(result)))
	{
		dhostid = DBget_maxid("dhosts");

		DBexecute("insert into dhosts (dhostid,druleid)"
				" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ")",
				dhostid, drule->druleid);

		DBexecute("update dservices"
				" set dhostid=" ZBX_FS_UI64
				" where dhostid=" ZBX_FS_UI64
					" and ip" ZBX_SQL_STRCMP,
				dhostid, dhost->dhostid, ZBX_SQL_STRVAL_EQ(ip_esc));

		dhost->dhostid = dhostid;
		dhost->status = DOBJECT_STATUS_DOWN;
		dhost->lastup = 0;
		dhost->lastdown = 0;
	}
	DBfree_result(result);

	zbx_free(sql);
	zbx_free(ip_esc);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
예제 #5
0
/******************************************************************************
 *                                                                            *
 * Function: get_discovered_agent_port                                        *
 *                                                                            *
 * Purpose: return port of the discovered zabbix_agent                        *
 *                                                                            *
 * Return value: discovered port number, otherwise default port - 10050       *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static unsigned short	get_discovered_agent_port(DB_EVENT *event)
{
	const char	*__function_name = "get_discovered_agent_port";
	DB_RESULT	result;
	DB_ROW		row;
	unsigned short	port = 10050;
	char		sql[256];

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

	if (event->source != EVENT_SOURCE_DISCOVERY)
		goto end;

	switch (event->object) {
	case EVENT_OBJECT_DHOST:
		zbx_snprintf(sql, sizeof(sql), "select port from dservices where type=%d and dhostid=" ZBX_FS_UI64
				" order by dserviceid",
				SVC_AGENT,
				event->objectid);
		break;
	case EVENT_OBJECT_DSERVICE:
		zbx_snprintf(sql, sizeof(sql), "select port from dservices where type=%d and"
				" dhostid in (select dhostid from dservices where dserviceid=" ZBX_FS_UI64 ")"
				" order by dserviceid",
				SVC_AGENT,
				event->objectid);
		break;
	default:
		goto end;
	}

	result = DBselectN(sql, 1);
	if (NULL != (row = DBfetch(result)))
	{
		port = atoi(row[0]);

		zabbix_log(LOG_LEVEL_DEBUG, "%s() port:%d",
				__function_name, (int)port);
	}
	DBfree_result(result);
end:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return port;
}
예제 #6
0
파일: history.c 프로젝트: rennhak/zabbix
/******************************************************************************
 *                                                                            *
 * Function : process_hstory_table_data:                                      *
 *                                                                            *
 * Purpose: process new history data                                          *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              * 
 *                                                                            *
 * Author: Aleksander Vladishev                                               *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	process_history_table_data(ZBX_TABLE *table, int master_nodeid, int nodeid)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		*data = NULL, *tmp = NULL;
	int		data_allocated = 1024*1024, tmp_allocated = 4096, tmp_offset, data_offset, f, fld, len;
	int		data_found = 0;
	zbx_uint64_t	lastid;
	int		lastclock = 0, clock;

	zabbix_log( LOG_LEVEL_DEBUG, "In process_history_table_data()");

	DBbegin();

	if ((table->flags & ZBX_HISTORY) && FAIL == get_history_lastid(master_nodeid, nodeid, table, &lastid))
		return;
	if ((table->flags & ZBX_HISTORY_TRENDS) && FAIL == get_trends_lastid(master_nodeid, nodeid, table, &lastid, &lastclock))
		return;

	data = zbx_malloc(data, data_allocated);
	tmp = zbx_malloc(tmp, tmp_allocated);

	data_offset = 0;
	zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "History%c%d%c%d%c%s",
		ZBX_DM_DELIMITER, CONFIG_NODEID,
		ZBX_DM_DELIMITER, nodeid,
		ZBX_DM_DELIMITER, table->table);

	/* Do not send history for current node if CONFIG_NODE_NOHISTORY is set */
/*	if ((CONFIG_NODE_NOHISTORY != 0) && (CONFIG_NODEID == nodeid))
		goto exit;*/

	tmp_offset = 0;
	if (table->flags & ZBX_HISTORY_SYNC) {
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "select %s,",
			table->recid);
	} else { /* ZBX_HISTORY, ZBX_HISTORY_TRENDS */
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 16, "select ");
	}

	for (f = 0; table->fields[f].name != 0; f++) {
		if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC))
			continue;

		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "%s,",
			table->fields[f].name);
	}
	tmp_offset--;

	if (table->flags & ZBX_HISTORY_SYNC) {
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where nodeid=%d order by %s",
			table->table,
			nodeid,
			table->recid);
	} else if (table->flags & ZBX_HISTORY_TRENDS) {
		clock = time(NULL) - 600; /* -10min */
		clock -= clock % 3600;

		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where"
			" (itemid>"ZBX_FS_UI64" or (itemid="ZBX_FS_UI64" and clock>%d)) and clock<%d"
			DB_NODE " order by itemid,clock",
			table->table,
			lastid, lastid, lastclock, clock,
			DBnode("itemid", nodeid));
	} else { /* ZBX_HISTORY */
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where %s>"ZBX_FS_UI64
			DB_NODE " order by %s",
			table->table,
			table->recid,
			lastid,
			DBnode(table->recid, nodeid),
			table->recid);
	}

	result = DBselectN(tmp, 10000);
	while (NULL != (row = DBfetch(result))) {
		if (table->flags & ZBX_HISTORY_SYNC) {
			ZBX_STR2UINT64(lastid, row[0]);
			fld = 1;
		} else
			fld = 0;

		zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n");

		for (f = 0; table->fields[f].name != 0; f++) {
			if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC))
				continue;

			if (table->fields[f].type == ZBX_TYPE_INT ||
				table->fields[f].type == ZBX_TYPE_UINT ||
				table->fields[f].type == ZBX_TYPE_ID ||
				table->fields[f].type == ZBX_TYPE_FLOAT)
			{
				zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "%s%c",
					row[fld], ZBX_DM_DELIMITER);
			} else { /* ZBX_TYPE_CHAR ZBX_TYPE_BLOB ZBX_TYPE_TEXT */
				len = (int)strlen(row[fld]);
				len = zbx_binary2hex((u_char *)row[fld], len, &tmp, &tmp_allocated);
				zbx_snprintf_alloc(&data, &data_allocated, &data_offset, len + 8, "%s%c",
					tmp, ZBX_DM_DELIMITER);
			}
			fld++;
		}
		data_offset--;
		data_found = 1;
	}
	DBfree_result(result);

	data[data_offset] = '\0';

	if (1 == data_found && SUCCEED == send_to_node(table->table, master_nodeid, nodeid, data)) {
		if (table->flags & ZBX_HISTORY_SYNC) {
			DBexecute("delete from %s where nodeid=%d and %s<="ZBX_FS_UI64,
				table->table,
				nodeid,
				table->recid,
				lastid);
		}
	}

	DBcommit();

	zbx_free(tmp);
	zbx_free(data);
}
예제 #7
0
/******************************************************************************
 *                                                                            *
 * Function: add host if not added already                                    *
 *                                                                            *
 * Purpose: add discovered host                                               *
 *                                                                            *
 * Parameters: dhostid - discovered host id                                   *
 *                                                                            *
 * Return value: hostid - new/existing hostid                                 *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static zbx_uint64_t	add_discovered_host(DB_EVENT *event)
{
	const char	*__function_name = "add_discovered_host";
	DB_RESULT	result;
	DB_RESULT	result2;
	DB_ROW		row;
	DB_ROW		row2;
	zbx_uint64_t	hostid = 0, proxy_hostid, host_proxy_hostid;
	char		host[MAX_STRING_LEN], *host_esc, *ip_esc, *host_unique, *host_unique_esc;
	int		port;
	zbx_uint64_t	groupid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s(eventid:" ZBX_FS_UI64 ")",
			__function_name, event->eventid);

	result = DBselect(
			"select discovery_groupid"
			" from config"
			" where 1=1"
				DB_NODE,
			DBnode_local("configid"));

	if (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(groupid, row[0]);
	}
	else
	{
		zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined");
		return 0;
	}
	DBfree_result(result);

	switch (event->object)
	{
		case EVENT_OBJECT_DHOST:
			result = DBselect(
					"select dr.proxy_hostid,ds.ip"
					" from drules dr,dchecks dc,dservices ds"
					" where dc.druleid=dr.druleid"
						" and ds.dcheckid=dc.dcheckid"
						" and ds.dhostid=" ZBX_FS_UI64
					" order by ds.dserviceid",
					event->objectid);
			break;
		case EVENT_OBJECT_DSERVICE:
			result = DBselect(
					"select dr.proxy_hostid,ds.ip"
					" from drules dr,dchecks dc,dservices ds,dservices ds1"
					" where dc.druleid=dr.druleid"
						" and ds.dcheckid=dc.dcheckid"
						" and ds1.dhostid=ds.dhostid"
						" and ds1.dserviceid=" ZBX_FS_UI64
					" order by ds.dserviceid",
					event->objectid);
			break;
		case EVENT_OBJECT_ZABBIX_ACTIVE:
			result = DBselect("select proxy_hostid,host from autoreg_host"
					" where autoreg_hostid=" ZBX_FS_UI64,
					event->objectid);
			break;
		default:
			return 0;
	}

	if (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(proxy_hostid, row[0]);

		if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object)
		{
			char	sql[512];

			host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN);

			zbx_snprintf(sql, sizeof(sql),
					"select hostid,proxy_hostid"
					" from hosts"
					" where host='%s'"
						DB_NODE
					" order by hostid",
					host_esc,
					DBnode_local("hostid"));

			result2 = DBselectN(sql, 1);

			if (NULL == (row2 = DBfetch(result2)))
			{
				hostid = DBget_maxid("hosts");

				DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,dns)"
						" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',0,'%s')",
						hostid, proxy_hostid, host_esc, host_esc);
			}
			else
			{
				ZBX_STR2UINT64(hostid, row2[0]);
				ZBX_STR2UINT64(host_proxy_hostid, row2[1]);

				if (host_proxy_hostid != proxy_hostid)
				{
					DBexecute("update hosts"
							" set proxy_hostid=" ZBX_FS_UI64
							" where hostid=" ZBX_FS_UI64,
							proxy_hostid, hostid);
				}
			}
			DBfree_result(result2);

			zbx_free(host_esc);
		}
		else	/* EVENT_OBJECT_DHOST, EVENT_OBJECT_DSERVICE */
		{
			alarm(CONFIG_TIMEOUT);
			zbx_gethost_by_ip(row[1], host, sizeof(host));
			alarm(0);

			host_esc = DBdyn_escape_string_len(host, HOST_HOST_LEN);
			ip_esc = DBdyn_escape_string_len(row[1], HOST_IP_LEN);

			port = get_discovered_agent_port(event);

			result2 = DBselect(
					"select hostid,dns,port,proxy_hostid"
					" from hosts"
					" where ip='%s'"
						DB_NODE,
					ip_esc,
					DBnode_local("hostid"));

			if (NULL == (row2 = DBfetch(result2)))
			{
				hostid = DBget_maxid("hosts");

				/* for host uniqueness purposes */
				if ('\0' != *host)
				{
					/* by host name */
					make_hostname(host);	/* replace not-allowed characters */
					host_unique = DBget_unique_hostname_by_sample(host);
				}
				else
				{
					/* by ip */
					make_hostname(row[1]);	/* replace not-allowed characters */
					host_unique = DBget_unique_hostname_by_sample(row[1]);
				}

				host_unique_esc = DBdyn_escape_string(host_unique);

				DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,ip,dns,port)"
						" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',1,'%s','%s',%d)",
						hostid, proxy_hostid, host_unique_esc, ip_esc, host_esc, port);

				zbx_free(host_unique);
				zbx_free(host_unique_esc);
			}
			else
			{
				ZBX_STR2UINT64(hostid, row2[0]);
				ZBX_STR2UINT64(host_proxy_hostid, row2[3]);

				if (0 != strcmp(host, row2[1]) || host_proxy_hostid != proxy_hostid)
				{
					DBexecute("update hosts"
							" set dns='%s',proxy_hostid=" ZBX_FS_UI64
							" where hostid=" ZBX_FS_UI64,
							host_esc, proxy_hostid, hostid);
				}
			}
			DBfree_result(result2);

			zbx_free(host_esc);
			zbx_free(ip_esc);
		}
	}
	DBfree_result(result);

	if (0 != hostid)
		add_discovered_host_group(hostid, groupid);

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

	return hostid;
}
예제 #8
0
파일: history_sql.c 프로젝트: zabbix/zabbix
/************************************************************************************
 *                                                                                  *
 * Function: db_read_values_by_time_and_count                                       *
 *                                                                                  *
 * Purpose: reads item history data from database                                   *
 *                                                                                  *
 * Parameters:  itemid        - [IN] the itemid                                     *
 *              value_type    - [IN] the value type (see ITEM_VALUE_TYPE_* defs)    *
 *              values        - [OUT] the item history data values                  *
 *              seconds       - [IN] the time period to read                        *
 *              count         - [IN] the number of values to read                   *
 *              end_timestamp - [IN] the value timestamp to start reading with      *
 *                                                                                  *
 * Return value: SUCCEED - the history data were read successfully                  *
 *               FAIL - otherwise                                                   *
 *                                                                                  *
 * Comments: this function reads <count> values from <seconds> period before        *
 *           <count_timestamp> (including) plus all values in range:                *
 *             count_timestamp < <value timestamp> <= read_timestamp                *
 *                                                                                  *
 ************************************************************************************/
static int	db_read_values_by_time_and_count(zbx_uint64_t itemid, int value_type,
		zbx_vector_history_record_t *values, int seconds, int count, int end_timestamp)
{
	int			ret = FAIL;
	char			*sql = NULL;
	size_t	 		sql_alloc = 0, sql_offset;
	DB_RESULT		result;
	DB_ROW			row;
	zbx_vc_history_table_t	*table = &vc_history_tables[value_type];

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select clock,ns,%s"
			" from %s"
			" where itemid=" ZBX_FS_UI64,
			table->fields, table->name, itemid);

	if (1 == seconds)
	{
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and clock=%d", end_timestamp);
	}
	else
	{
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and clock>%d and clock<=%d order by clock desc",
				end_timestamp - seconds, end_timestamp);
	}

	result = DBselectN(sql, count);

	zbx_free(sql);

	if (NULL == result)
		goto out;

	while (NULL != (row = DBfetch(result)) && 0 < count--)
	{
		zbx_history_record_t	value;

		value.timestamp.sec = atoi(row[0]);
		value.timestamp.ns = atoi(row[1]);
		table->rtov(&value.value, row + 2);

		zbx_vector_history_record_append_ptr(values, &value);
	}
	DBfree_result(result);

	if (0 < count)
	{
		/* no more data in the specified time period, return success */
		ret = SUCCEED;
		goto out;
	}

	/* Drop data from the last second and read the whole second again     */
	/* to ensure that data is cached by seconds.                          */
	/* Because the initial select has limit option (DBselectN()) we have  */
	/* to perform another select to read the last second data.            */
	end_timestamp = values->values[values->values_num - 1].timestamp.sec;

	while (0 < values->values_num && values->values[values->values_num - 1].timestamp.sec == end_timestamp)
	{
		values->values_num--;
		zbx_history_record_clear(&values->values[values->values_num], value_type);
	}

	ret = db_read_values_by_time(itemid, value_type, values, 1, end_timestamp);
out:
	zbx_free(sql);

	return ret;
}
예제 #9
0
파일: history_sql.c 프로젝트: zabbix/zabbix
/************************************************************************************
 *                                                                                  *
 * Function: db_read_values_by_count                                                *
 *                                                                                  *
 * Purpose: reads item history data from database                                   *
 *                                                                                  *
 * Parameters:  itemid        - [IN] the itemid                                     *
 *              value_type    - [IN] the value type (see ITEM_VALUE_TYPE_* defs)    *
 *              values        - [OUT] the item history data values                  *
 *              count         - [IN] the number of values to read                   *
 *              end_timestamp - [IN] the value timestamp to start reading with      *
 *                                                                                  *
 * Return value: SUCCEED - the history data were read successfully                  *
 *               FAIL - otherwise                                                   *
 *                                                                                  *
 * Comments: this function reads <count> values before <count_timestamp> (including)*
 *           plus all values in range:                                              *
 *             count_timestamp < <value timestamp> <= read_timestamp                *
 *                                                                                  *
 *           To speed up the reading time with huge data loads, data is read by     *
 *           smaller time segments (hours, day, week, month) and the next (larger)  *
 *           time segment is read only if the requested number of values (<count>)  *
 *           is not yet retrieved.                                                  *
 *                                                                                  *
 ************************************************************************************/
static int	db_read_values_by_count(zbx_uint64_t itemid, int value_type, zbx_vector_history_record_t *values,
		int count, int end_timestamp)
{
	char			*sql = NULL;
	size_t	 		sql_alloc = 0, sql_offset;
	int			clock_to, clock_from, step = 0, ret = FAIL;
	DB_RESULT		result;
	DB_ROW			row;
	zbx_vc_history_table_t	*table = &vc_history_tables[value_type];
	const int		periods[] = {SEC_PER_HOUR, SEC_PER_DAY, SEC_PER_WEEK, SEC_PER_MONTH, 0, -1};

	clock_to = end_timestamp;

	while (-1 != periods[step] && 0 < count)
	{
		if (0 > (clock_from = clock_to - periods[step]))
		{
			clock_from = clock_to;
			step = 4;
		}

		sql_offset = 0;
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				"select clock,ns,%s"
				" from %s"
				" where itemid=" ZBX_FS_UI64
					" and clock<=%d",
				table->fields, table->name, itemid, clock_to);

		if (clock_from != clock_to)
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and clock>%d", clock_from);

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by clock desc");

		result = DBselectN(sql, count);

		if (NULL == result)
			goto out;

		while (NULL != (row = DBfetch(result)))
		{
			zbx_history_record_t	value;

			value.timestamp.sec = atoi(row[0]);
			value.timestamp.ns = atoi(row[1]);
			table->rtov(&value.value, row + 2);

			zbx_vector_history_record_append_ptr(values, &value);

			count--;
		}
		DBfree_result(result);

		clock_to -= periods[step];
		step++;
	}


	if (0 < count)
	{
		/* no more data in database, return success */
		ret = SUCCEED;
		goto out;
	}

	/* drop data from the last second and read the whole second again  */
	/* to ensure that data is cached by seconds                        */
	end_timestamp = values->values[values->values_num - 1].timestamp.sec;

	while (0 < values->values_num && values->values[values->values_num - 1].timestamp.sec == end_timestamp)
	{
		values->values_num--;
		zbx_history_record_clear(&values->values[values->values_num], value_type);
	}

	ret = db_read_values_by_time(itemid, value_type, values, 1, end_timestamp);
out:
	zbx_free(sql);

	return ret;
}
예제 #10
0
/******************************************************************************
 *                                                                            *
 * Function: add_discovered_host                                              *
 *                                                                            *
 * Purpose: add discovered host if it was not added already                   *
 *                                                                            *
 * Parameters: dhostid - discovered host id                                   *
 *                                                                            *
 * Return value: hostid - new/existing hostid                                 *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static zbx_uint64_t	add_discovered_host(const DB_EVENT *event)
{
	const char		*__function_name = "add_discovered_host";

	DB_RESULT		result;
	DB_RESULT		result2;
	DB_ROW			row;
	DB_ROW			row2;
	zbx_uint64_t		dhostid, hostid = 0, proxy_hostid;
	char			*host = NULL, *host_esc, *host_unique;
	unsigned short		port;
	zbx_uint64_t		groupid;
	zbx_vector_uint64_t	groupids;
	unsigned char		svc_type, interface_type;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64, __function_name, event->eventid);

	zbx_vector_uint64_create(&groupids);

	if (0 == *(zbx_uint64_t *)DCconfig_get_config_data(&groupid, CONFIG_DISCOVERY_GROUPID))
	{
		zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined");
		goto clean;
	}

	zbx_vector_uint64_append(&groupids, groupid);

	if (EVENT_OBJECT_DHOST == event->object || EVENT_OBJECT_DSERVICE == event->object)
	{
		if (EVENT_OBJECT_DHOST == event->object)
		{
			result = DBselect(
					"select ds.dhostid,dr.proxy_hostid,ds.ip,ds.dns,ds.port,ds.type"
					" from drules dr,dchecks dc,dservices ds"
					" where dc.druleid=dr.druleid"
						" and ds.dcheckid=dc.dcheckid"
						" and ds.dhostid=" ZBX_FS_UI64
					" order by ds.dserviceid",
					event->objectid);
		}
		else
		{
			result = DBselect(
					"select ds.dhostid,dr.proxy_hostid,ds.ip,ds.dns,ds.port,ds.type"
					" from drules dr,dchecks dc,dservices ds,dservices ds1"
					" where dc.druleid=dr.druleid"
						" and ds.dcheckid=dc.dcheckid"
						" and ds1.dhostid=ds.dhostid"
						" and ds1.dserviceid=" ZBX_FS_UI64
					" order by ds.dserviceid",
					event->objectid);
		}

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(dhostid, row[0]);
			ZBX_DBROW2UINT64(proxy_hostid, row[1]);
			svc_type = (unsigned char)atoi(row[5]);

			switch (svc_type)
			{
				case SVC_AGENT:
					port = (unsigned short)atoi(row[4]);
					interface_type = INTERFACE_TYPE_AGENT;
					break;
				case SVC_SNMPv1:
				case SVC_SNMPv2c:
				case SVC_SNMPv3:
					port = (unsigned short)atoi(row[4]);
					interface_type = INTERFACE_TYPE_SNMP;
					break;
				default:
					port = ZBX_DEFAULT_AGENT_PORT;
					interface_type = INTERFACE_TYPE_AGENT;
			}

			if (0 == hostid)
			{
				result2 = DBselect(
						"select distinct h.hostid"
						" from hosts h,interface i,dservices ds"
						" where h.hostid=i.hostid"
							" and i.ip=ds.ip"
							" and h.proxy_hostid%s"
							" and ds.dhostid=" ZBX_FS_UI64
							ZBX_SQL_NODE
						" order by h.hostid",
						DBsql_id_cmp(proxy_hostid),
						dhostid,
						DBand_node_local("h.hostid"));

				if (NULL != (row2 = DBfetch(result2)))
					ZBX_STR2UINT64(hostid, row2[0]);

				DBfree_result(result2);
			}

			if (0 == hostid)
			{
				hostid = DBget_maxid("hosts");

				/* for host uniqueness purposes */
				host = zbx_strdup(host, '\0' != *row[3] ? row[3] : row[2]);

				make_hostname(host);	/* replace not-allowed symbols */
				host_unique = DBget_unique_hostname_by_sample(host);
				host_esc = DBdyn_escape_string(host_unique);

				zbx_free(host);

				DBexecute("insert into hosts"
							" (hostid,proxy_hostid,host,name)"
						" values"
							" (" ZBX_FS_UI64 ",%s,'%s','%s')",
						hostid, DBsql_id_ins(proxy_hostid), host_esc, host_esc);

				DBadd_interface(hostid, interface_type, 1, row[2], row[3], port);

				zbx_free(host_unique);
				zbx_free(host_esc);

				add_discovered_host_groups(hostid, &groupids);
			}
			else
			{
				DBadd_interface(hostid, interface_type, 1, row[2], row[3], port);
			}
		}
		DBfree_result(result);
	}
	else if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object)
	{
		result = DBselect(
				"select proxy_hostid,host,listen_ip,listen_dns,listen_port"
				" from autoreg_host"
				" where autoreg_hostid=" ZBX_FS_UI64,
				event->objectid);

		if (NULL != (row = DBfetch(result)))
		{
			char		*sql = NULL;
			zbx_uint64_t	host_proxy_hostid;

			ZBX_DBROW2UINT64(proxy_hostid, row[0]);
			host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN);
			port = (unsigned short)atoi(row[4]);

			result2 = DBselect(
					"select null"
					" from hosts"
					" where host='%s'"
						" and status=%d",
					host_esc, HOST_STATUS_TEMPLATE);

			if (NULL != (row2 = DBfetch(result2)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host \"%s\":"
						" template with the same name already exists", row[1]);
				DBfree_result(result2);
				goto out;
			}
			DBfree_result(result2);

			sql = zbx_dsprintf(sql,
					"select hostid,proxy_hostid"
					" from hosts"
					" where host='%s'"
						" and flags<>%d"
						" and status in (%d,%d)"
						ZBX_SQL_NODE
					" order by hostid",
					host_esc, ZBX_FLAG_DISCOVERY_PROTOTYPE,
					HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
					DBand_node_local("hostid"));

			result2 = DBselectN(sql, 1);

			zbx_free(sql);

			if (NULL == (row2 = DBfetch(result2)))
			{
				hostid = DBget_maxid("hosts");

				DBexecute("insert into hosts"
							" (hostid,proxy_hostid,host,name)"
						" values"
							" (" ZBX_FS_UI64 ",%s,'%s','%s')",
						hostid, DBsql_id_ins(proxy_hostid), host_esc, host_esc);

				DBadd_interface(hostid, INTERFACE_TYPE_AGENT, 1, row[2], row[3], port);

				add_discovered_host_groups(hostid, &groupids);
			}
			else
			{
				ZBX_STR2UINT64(hostid, row2[0]);
				ZBX_DBROW2UINT64(host_proxy_hostid, row2[1]);

				if (host_proxy_hostid != proxy_hostid)
				{
					DBexecute("update hosts"
							" set proxy_hostid=%s"
							" where hostid=" ZBX_FS_UI64,
							DBsql_id_ins(proxy_hostid), hostid);
				}

				DBadd_interface(hostid, INTERFACE_TYPE_AGENT, 1, row[2], row[3], port);
			}
			DBfree_result(result2);
out:
			zbx_free(host_esc);
		}
		DBfree_result(result);
	}
clean:
	zbx_vector_uint64_destroy(&groupids);

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

	return hostid;
}
예제 #11
0
파일: timer.c 프로젝트: Metalaria/Zabbix_
/******************************************************************************
 *                                                                            *
 * Function: get_trigger_values                                               *
 *                                                                            *
 * Purpose: get trigger values for specified period                           *
 *                                                                            *
 * Parameters: triggerid        - [IN] trigger identifier from database       *
 *             maintenance_from - [IN] maintenance period start               *
 *             maintenance_to   - [IN] maintenance period stop                *
 *             value_before     - [OUT] trigger value before maintenance      *
 *             value_inside     - [OUT] trigger value inside maintenance      *
 *                                      (only if value_before=value_after)    *
 *             value_after      - [OUT] trigger value after maintenance       *
 *                                                                            *
 * Return value: SUCCEED if found event with OK or PROBLEM statuses           *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	get_trigger_values(zbx_uint64_t triggerid, int maintenance_from, int maintenance_to,
		unsigned char *value_before, unsigned char *value_inside, unsigned char *value_after)
{
	const char	*__function_name = "get_trigger_values";

	DB_RESULT	result;
	DB_ROW		row;
	char		sql[256];
	int		clock;

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

	zabbix_log(LOG_LEVEL_DEBUG, "%s() from:'%s %s'", __function_name,
			zbx_date2str(maintenance_from), zbx_time2str(maintenance_from));
	zabbix_log(LOG_LEVEL_DEBUG, "%s() to:'%s %s'", __function_name,
			zbx_date2str(maintenance_to), zbx_time2str(maintenance_to));

	/* check for value after maintenance period */
	zbx_snprintf(sql, sizeof(sql),
			"select clock,value"
			" from events"
			" where source=%d"
				" and object=%d"
				" and objectid=" ZBX_FS_UI64
				" and clock<%d"
			" order by clock desc,eventid desc",
			EVENT_SOURCE_TRIGGERS,
			EVENT_OBJECT_TRIGGER,
			triggerid,
			maintenance_to);

	result = DBselectN(sql, 1);

	if (NULL != (row = DBfetch(result)))
	{
		clock = atoi(row[0]);
		*value_after = atoi(row[1]);
	}
	else
	{
		clock = 0;
		*value_after = TRIGGER_VALUE_UNKNOWN;
	}
	DBfree_result(result);

	/* if no events inside maintenance */
	if (clock < maintenance_from)
	{
		*value_before = *value_after;
		*value_inside = *value_after;
		goto out;
	}

	/* check for value before maintenance period */
	zbx_snprintf(sql, sizeof(sql),
			"select value"
			" from events"
			" where source=%d"
				" and object=%d"
				" and objectid=" ZBX_FS_UI64
				" and clock<%d"
			" order by clock desc,eventid desc",
			EVENT_SOURCE_TRIGGERS,
			EVENT_OBJECT_TRIGGER,
			triggerid,
			maintenance_from);

	result = DBselectN(sql, 1);

	if (NULL != (row = DBfetch(result)))
		*value_before = atoi(row[0]);
	else
		*value_before = TRIGGER_VALUE_UNKNOWN;
	DBfree_result(result);

	if (*value_after != *value_before)
	{
		*value_inside = TRIGGER_VALUE_UNKNOWN;	/* not important what value is here */
		goto out;
	}

	/* check for value inside maintenance period */
	result = DBselect(
			"select value"
			" from events"
			" where source=%d"
				" and object=%d"
				" and objectid=" ZBX_FS_UI64
				" and clock between %d and %d"
				" and value=%d"
			" order by object desc,objectid desc,eventid desc",
			EVENT_SOURCE_TRIGGERS,
			EVENT_OBJECT_TRIGGER,
			triggerid,
			maintenance_from, maintenance_to - 1,
			*value_after == TRIGGER_VALUE_OK ? TRIGGER_VALUE_PROBLEM : TRIGGER_VALUE_OK);

	if (NULL != (row = DBfetch(result)))
		*value_inside = atoi(row[0]);
	else
		*value_inside = *value_before;
	DBfree_result(result);
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s() before:%d inside:%d after:%d",
			__function_name, (int)*value_before, (int)*value_inside, (int)*value_after);
}