Ejemplo n.º 1
0
static void	add_command_alert(DC_HOST *host, zbx_uint64_t eventid, zbx_uint64_t actionid,
		int esc_step, const char *command, zbx_alert_status_t status, const char *error)
{
	const char	*__function_name = "add_command_alert";
	zbx_uint64_t	alertid;
	int		now;
	char		*tmp = NULL, *command_esc, *error_esc;

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

	alertid = DBget_maxid("alerts");
	now = (int)time(NULL);
	tmp = zbx_dsprintf(tmp, "%s:%s", host->host, NULL == command ? "" : command);
	command_esc = DBdyn_escape_string_len(tmp, ALERT_MESSAGE_LEN);
	error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN);
	zbx_free(tmp);

	DBexecute("insert into alerts"
			" (alertid,actionid,eventid,clock,message,status,error,alerttype,esc_step)"
			" values "
			"(" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,'%s',%d,'%s',%d,%d)",
			alertid, actionid, eventid, now, command_esc, (int)status,
			error_esc, ALERT_TYPE_COMMAND, esc_step);

	zbx_free(error_esc);
	zbx_free(command_esc);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Ejemplo n.º 2
0
/******************************************************************************
 *                                                                            *
 * Function: proxy_update_host                                                *
 *                                                                            *
 * Purpose: process new service status                                        *
 *                                                                            *
 * Parameters: service - service info                                         *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static void	proxy_update_host(DB_DRULE *drule, const char *ip, const char *dns, int status, int now)
{
	char	*ip_esc, *dns_esc;

	ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN);
	dns_esc = DBdyn_escape_string_len(dns, INTERFACE_DNS_LEN);

	DBexecute("insert into proxy_dhistory (clock,druleid,type,ip,dns,status)"
			" values (%d," ZBX_FS_UI64 ",-1,'%s','%s',%d)",
			now, drule->druleid, ip_esc, dns_esc, status);

	zbx_free(dns_esc);
	zbx_free(ip_esc);
}
Ejemplo n.º 3
0
static int	DBpatch_2010176(void)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		*name, *name_esc;
	int		ret = SUCCEED;

	result = DBselect("select scriptid,name from scripts");

	while (SUCCEED == ret && NULL != (row = DBfetch(result)))
	{
		name = zbx_dyn_escape_string(row[1], "/\\");

		if (0 != strcmp(name, row[1]))
		{
			name_esc = DBdyn_escape_string_len(name, 255);

			if (ZBX_DB_OK > DBexecute("update scripts set name='%s' where scriptid=%s", name_esc, row[0]))
				ret = FAIL;

			zbx_free(name_esc);
		}

		zbx_free(name);
	}
	DBfree_result(result);

	return ret;
}
Ejemplo n.º 4
0
/******************************************************************************
 *                                                                            *
 * Function: convert_triggers_expression                                      *
 *                                                                            *
 * Purpose: convert trigger expressions to new node ID                        *
 *                                                                            *
 * Parameters: old_id - old id, new_id - new node id                          *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	convert_triggers_expression(int old_id, int new_id)
{
	zbx_uint64_t	prefix;
	const ZBX_TABLE	*r_table;
	DB_RESULT	result;
	DB_ROW		row;
	char		new_expression[MAX_STRING_LEN], *new_expression_esc;

	r_table = DBget_table("functions");
	assert(NULL != r_table);

	prefix = (zbx_uint64_t)__UINT64_C(100000000000000) * (zbx_uint64_t)new_id;
	if (0 != (r_table->flags & ZBX_SYNC))
		prefix += (zbx_uint64_t)__UINT64_C(100000000000) * (zbx_uint64_t)new_id;

	result = DBselect("select expression,triggerid from triggers");

	while (NULL != (row = DBfetch(result)))
	{
		memset(new_expression, 0, sizeof(new_expression));
		convert_expression(old_id, new_id, prefix, row[0], new_expression);

		new_expression_esc = DBdyn_escape_string_len(new_expression, TRIGGER_EXPRESSION_LEN);
		DBexecute("update triggers set expression='%s' where triggerid=%s",
				new_expression_esc, row[1]);
		zbx_free(new_expression_esc);
	}
	DBfree_result(result);
}
Ejemplo n.º 5
0
/******************************************************************************
 *                                                                            *
 * Function: DBlld_get_item                                                   *
 *                                                                            *
 * Purpose: finds item in the selected host by an item prototype key and      *
 *          discovered data                                                   *
 *                                                                            *
 ******************************************************************************/
int	DBlld_get_item(zbx_uint64_t hostid, const char *tmpl_key, struct zbx_json_parse *jp_row, zbx_uint64_t *itemid)
{
	const char	*__function_name = "DBlld_get_item";

	DB_RESULT	result;
	DB_ROW		row;
	char		*key = NULL, *key_esc;
	int		res = SUCCEED;

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

	if (NULL != jp_row)
	{
		key = zbx_strdup(key, tmpl_key);
		substitute_key_macros(&key, NULL, NULL, jp_row, MACRO_TYPE_ITEM_KEY, NULL, 0);
		key_esc = DBdyn_escape_string_len(key, ITEM_KEY_LEN);
	}
	else
		key_esc = DBdyn_escape_string_len(tmpl_key, ITEM_KEY_LEN);

	result = DBselect(
			"select itemid"
			" from items"
			" where hostid=" ZBX_FS_UI64
				" and key_='%s'",
			hostid, key_esc);

	zbx_free(key_esc);
	zbx_free(key);

	if (NULL == (row = DBfetch(result)))
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot find item [%s] on the host",
				__function_name, key);
		res = FAIL;
	}
	else
		ZBX_STR2UINT64(*itemid, row[0]);

	DBfree_result(result);

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

	return res;
}
Ejemplo n.º 6
0
/******************************************************************************
 *                                                                            *
 * Function: proxy_update_service                                             *
 *                                                                            *
 * Purpose: process new service status                                        *
 *                                                                            *
 * Parameters: service - service info                                         *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static void	proxy_update_service(DB_DRULE *drule, DB_DCHECK *dcheck, const char *ip,
		const char *dns, int port, int status, const char *value, int now)
{
	char	*ip_esc, *dns_esc, *key_esc, *value_esc;

	ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN);
	dns_esc = DBdyn_escape_string_len(dns, INTERFACE_DNS_LEN);
	key_esc = DBdyn_escape_string_len(dcheck->key_, PROXY_DHISTORY_KEY_LEN);
	value_esc = DBdyn_escape_string_len(value, PROXY_DHISTORY_VALUE_LEN);

	DBexecute("insert into proxy_dhistory (clock,druleid,dcheckid,type,ip,dns,port,key_,value,status)"
			" values (%d," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,'%s','%s',%d,'%s','%s',%d)",
			now, drule->druleid, dcheck->dcheckid, dcheck->type,
			ip_esc, dns_esc, port, key_esc, value_esc, status);

	zbx_free(value_esc);
	zbx_free(key_esc);
	zbx_free(dns_esc);
	zbx_free(ip_esc);
}
Ejemplo n.º 7
0
/******************************************************************************
 *                                                                            *
 * Function: discovery_update_dservice_value                                  *
 *                                                                            *
 * Purpose: update discovered service details                                 *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static void	discovery_update_dservice_value(DB_DSERVICE *service)
{
	char	*value_esc;

	value_esc = DBdyn_escape_string_len(service->value, DSERVICE_VALUE_LEN);

	DBexecute("update dservices set value='%s' where dserviceid=" ZBX_FS_UI64,
			value_esc, service->dserviceid);

	zbx_free(value_esc);
}
Ejemplo n.º 8
0
/******************************************************************************
 *                                                                            *
 * Function: proxy_update_host                                                *
 *                                                                            *
 * Purpose: process new service status                                        *
 *                                                                            *
 * Parameters: service - service info                                         *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void proxy_update_host(DB_DRULE *drule, char *ip, int status, int now)
{
	char	*ip_esc;

	ip_esc = DBdyn_escape_string_len(ip, PROXY_DHISTORY_IP_LEN);

	DBexecute("insert into proxy_dhistory (clock,druleid,type,ip,status)"
			" values (%d," ZBX_FS_UI64 ",-1,'%s',%d)",
			now,
			drule->druleid,
			ip_esc,
			status);

	zbx_free(ip_esc);
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
static DB_RESULT	discovery_get_dhost_by_ip(zbx_uint64_t druleid, const char *ip)
{
	DB_RESULT	result;
	char		*ip_esc;

	ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN);

	result = DBselect(
			"select dh.dhostid,dh.status,dh.lastup,dh.lastdown"
			" from dhosts dh,dservices ds"
			" where ds.dhostid=dh.dhostid"
				" and dh.druleid=" ZBX_FS_UI64
				" and ds.ip" ZBX_SQL_STRCMP
			" order by dh.dhostid",
			druleid, ZBX_SQL_STRVAL_EQ(ip_esc));

	zbx_free(ip_esc);

	return result;
}
Ejemplo n.º 11
0
static DB_RESULT	discovery_get_dhost_by_value(zbx_uint64_t dcheckid, const char *value)
{
	DB_RESULT	result;
	char		*value_esc;

	value_esc = DBdyn_escape_string_len(value, DSERVICE_VALUE_LEN);

	result = DBselect(
			"select dh.dhostid,dh.status,dh.lastup,dh.lastdown"
			" from dhosts dh,dservices ds"
			" where ds.dhostid=dh.dhostid"
				" and ds.dcheckid=" ZBX_FS_UI64
				" and ds.value" ZBX_SQL_STRCMP
			" order by dh.dhostid",
			dcheckid, ZBX_SQL_STRVAL_EQ(value_esc));

	zbx_free(value_esc);

	return result;
}
Ejemplo n.º 12
0
static void	add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action,
		zbx_uint64_t userid, zbx_uint64_t mediatypeid, const char *subject, const char *message)
{
	const char	*__function_name = "add_message_alert";

	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	alertid;
	int		now, severity, medias = 0;
	char		*subject_dyn, *message_dyn, *sendto_esc, *subject_esc, *message_esc, *error_esc;
	char		error[MAX_STRING_LEN];

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

	subject_dyn = zbx_strdup(NULL, subject);
	message_dyn = zbx_strdup(NULL, message);

	substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &subject_dyn, MACRO_TYPE_MESSAGE, NULL, 0);
	substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &message_dyn, MACRO_TYPE_MESSAGE, NULL, 0);

	now = time(NULL);
	subject_esc = DBdyn_escape_string_len(subject_dyn, ALERT_SUBJECT_LEN);
	message_esc = DBdyn_escape_string_len(message_dyn, ALERT_MESSAGE_LEN);

	zbx_free(subject_dyn);
	zbx_free(message_dyn);

	if (0 == mediatypeid)
	{
		result = DBselect(
				"select m.mediatypeid,m.sendto,m.severity,m.period,mt.status"
				" from media m,media_type mt"
				" where m.mediatypeid=mt.mediatypeid"
					" and m.active=%d"
					" and m.userid=" ZBX_FS_UI64,
				MEDIA_STATUS_ACTIVE, userid);
	}
	else
	{
		result = DBselect(
				"select m.mediatypeid,m.sendto,m.severity,m.period,mt.status"
				" from media m,media_type mt"
				" where m.mediatypeid=mt.mediatypeid"
					" and m.active=%d"
					" and m.userid=" ZBX_FS_UI64
					" and m.mediatypeid=" ZBX_FS_UI64,
				MEDIA_STATUS_ACTIVE, userid, mediatypeid);
	}

	while (NULL != (row = DBfetch(result)))
	{
		medias		= 1;

		ZBX_STR2UINT64(mediatypeid, row[0]);
		severity	= atoi(row[2]);

		zabbix_log(LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]",
				(int)event->trigger.priority, severity, row[3]);

		if (((1 << event->trigger.priority) & severity) == 0)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (severity)");
			continue;
		}

		if (FAIL == check_time_period(row[3], (time_t)NULL))
		{
			zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (period)");
			continue;
		}

		alertid		= DBget_maxid("alerts");
		sendto_esc	= DBdyn_escape_string_len(row[1], ALERT_SENDTO_LEN);

		if (MEDIA_TYPE_STATUS_ACTIVE == atoi(row[4]))
		{
			DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock"
					",mediatypeid,sendto,subject,message,status,alerttype,esc_step)"
					" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d"
					"," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)",
					alertid,
					action->actionid,
					event->eventid,
					userid,
					now,
					mediatypeid,
					sendto_esc,
					subject_esc,
					message_esc,
					ALERT_STATUS_NOT_SENT,
					ALERT_TYPE_MESSAGE,
					escalation->esc_step);
		}
		else
		{
			error_esc = DBdyn_escape_string("Media type disabled");

			DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock"
					",mediatypeid,sendto,subject,message,status,alerttype,esc_step,error)"
					" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d"
					"," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d,'%s')",
					alertid,
					action->actionid,
					event->eventid,
					userid,
					now,
					mediatypeid,
					sendto_esc,
					subject_esc,
					message_esc,
					ALERT_STATUS_FAILED,
					ALERT_TYPE_MESSAGE,
					escalation->esc_step,
					error_esc);

			zbx_free(error_esc);
		}

		zbx_free(sendto_esc);
	}

	DBfree_result(result);

	if (0 == medias)
	{
		zbx_snprintf(error, sizeof(error), "No media defined for user \"%s\"",
				zbx_user_string(userid));

		alertid		= DBget_maxid("alerts");
		error_esc	= DBdyn_escape_string(error);

		DBexecute("insert into alerts (alertid,actionid,eventid,userid,retries,clock"
				",subject,message,status,alerttype,error,esc_step)"
				" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d"
				",'%s','%s',%d,%d,'%s',%d)",
				alertid,
				action->actionid,
				event->eventid,
				userid,
				ALERT_MAX_RETRIES,
				now,
				subject_esc,
				message_esc,
				ALERT_STATUS_FAILED,
				ALERT_TYPE_MESSAGE,
				error_esc,
				escalation->esc_step);

		zbx_free(error_esc);
	}

	zbx_free(subject_esc);
	zbx_free(message_esc);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Ejemplo n.º 13
0
/******************************************************************************
 *                                                                            *
 * Function: DCflush_nextchecks                                               *
 *                                                                            *
 * Purpose: add item nextcheck to the array                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexander Vladishev, Dmitry Borovikov                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	DCflush_nextchecks()
{
	const char	*__function_name = "DCflush_nextchecks";

	int		i, sql_offset = 0, sql_allocated = 4096;
	char		*sql = NULL;

	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	triggerid;
	zbx_uint64_t	itemid;
	zbx_uint64_t	events_maxid = 0;
	char		*error_msg_esc = NULL;

	char		*sql_select = NULL;
	int		sql_select_offset = 0, sql_select_allocated = 512;

	/* a crutch for the function `DBadd_condition_alloc' */
	zbx_uint64_t	*ids = NULL;
	int		ids_allocated = 0, ids_num = 0;

	zbx_uint64_t	*triggerids = NULL;
	int		triggerids_allocated = 0, triggerids_num = 0;

	struct event_objectid_clock 	*events = NULL;
	int		events_num = 0, events_allocated = 32;

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

	if (nextcheck_num == 0)
		return;

	sql = zbx_malloc(sql, sql_allocated);

	DBbegin();

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n");
#endif

	/* dealing with items */
	for (i = 0; i < nextcheck_num; i++)
	{
		if (NULL == nextchecks[i].error_msg)
			continue;

		uint64_array_add(&ids, &ids_allocated, &ids_num, nextchecks[i].itemid, 64);

		error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, ITEM_ERROR_LEN);
		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc),
				"update items set status=%d,lastclock=%d,error='%s' where itemid=" ZBX_FS_UI64 ";\n",
				ITEM_STATUS_NOTSUPPORTED,
				(int)nextchecks[i].now,
				error_msg_esc,
				nextchecks[i].itemid);
		zbx_free(error_msg_esc);

		DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset);
	}

	/* dealing with notsupported items */
	if (ids_num > 0)
	{
		sql_select = zbx_malloc(sql_select, sql_select_allocated);
		events = zbx_malloc(events, events_allocated * sizeof(struct event_objectid_clock));

		/* preparing triggers */
		zbx_snprintf_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, 256,
				"select t.triggerid,i.itemid"
				" from triggers t,functions f,items i"
				" where t.triggerid=f.triggerid"
					" and f.itemid=i.itemid"
					" and t.status in (%d)"
					" and t.value not in (%d)"
					" and",
				TRIGGER_STATUS_ENABLED,
				TRIGGER_VALUE_UNKNOWN);
		DBadd_condition_alloc(&sql_select, &sql_select_allocated, &sql_select_offset,
				"i.itemid", ids, ids_num);
		result = DBselect("%s", sql_select);

		zbx_free(sql_select);

		/* processing triggers */
		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(triggerid, row[0]);
			ZBX_STR2UINT64(itemid, row[1]);

			/* do not generate multiple unknown events for a trigger */
			if (SUCCEED == uint64_array_exists(triggerids, triggerids_num, triggerid))
				continue;

			uint64_array_add(&triggerids, &triggerids_allocated, &triggerids_num, triggerid, 64);

			/* index `i' will surely contain necessary itemid */
			i = get_nearestindex(nextchecks, sizeof(ZBX_DC_NEXTCHECK), nextcheck_num, itemid);

			if (i == nextcheck_num || nextchecks[i].itemid != itemid)
			{
				THIS_SHOULD_NEVER_HAPPEN;
				continue;
			}

			error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, TRIGGER_ERROR_LEN);
			zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc),
					"update triggers set value=%d,lastchange=%d,error='%s' where triggerid=" ZBX_FS_UI64";\n",
							TRIGGER_VALUE_UNKNOWN,
							nextchecks[i].now,
							error_msg_esc,
							triggerid);
			zbx_free(error_msg_esc);

			if (events_num == events_allocated)
			{
				events_allocated += 32;
				events = zbx_realloc(events, events_allocated * sizeof(struct event_objectid_clock));
			}
			events[events_num].objectid = triggerid;
			events[events_num].clock = nextchecks[i].now;
			events_num++;

			DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset);
		}
		DBfree_result(result);

		/* dealing with events */
		for (i = 0; i < events_num; i++)
		{
			events_maxid = DBget_maxid("events");

			zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 256,
					"insert into events (eventid,source,object,objectid,clock,value) "
					"values (" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d);\n",
					events_maxid,
					EVENT_SOURCE_TRIGGERS,
					EVENT_OBJECT_TRIGGER,
					events[i].objectid,
					events[i].clock,
					TRIGGER_VALUE_UNKNOWN);

			DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset);
		}

		zbx_free(events);
	}

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n");
#endif

	if (sql_offset > 16)	/* In ORACLE always present begin..end; */
		DBexecute("%s", sql);

	zbx_free(sql);
	zbx_free(ids);
	zbx_free(triggerids);

	DCrelease_nextchecks();

	DBcommit();

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
static void	add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action,
		zbx_uint64_t userid, zbx_uint64_t mediatypeid, char *subject, char *message)
{
	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	alertid;
	int		now, severity, medias = 0;
	char		*sendto_esc, *subject_esc, *message_esc, *error_esc;
	char		error[MAX_STRING_LEN];

	zabbix_log(LOG_LEVEL_DEBUG, "In add_message_alert()");
/*	zabbix_log(LOG_LEVEL_DEBUG,"MESSAGE\n\tuserid : " ZBX_FS_UI64 "\n\tsubject: %s\n\tmessage: %s", userid, subject, message);*/

	now		= time(NULL);
	subject_esc	= DBdyn_escape_string_len(subject, ALERT_SUBJECT_LEN);
	message_esc	= DBdyn_escape_string(message);

	if (0 == mediatypeid)
	{
		result = DBselect("select mediatypeid,sendto,severity,period from media"
				" where active=%d and userid=" ZBX_FS_UI64,
				MEDIA_STATUS_ACTIVE,
				userid);
	}
	else
	{
		result = DBselect("select mediatypeid,sendto,severity,period from media"
				" where active=%d and userid=" ZBX_FS_UI64 " and mediatypeid=" ZBX_FS_UI64,
				MEDIA_STATUS_ACTIVE,
				userid,
				mediatypeid);
	}

	while (NULL != (row = DBfetch(result))) {
		medias		= 1;

		ZBX_STR2UINT64(mediatypeid, row[0]);
		severity	= atoi(row[2]);

		zabbix_log( LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]",
			event->trigger_priority,
			severity,
			row[3]);

		if (((1 << event->trigger_priority) & severity) == 0) {
			zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (severity)");
			continue;
		}

		if (check_time_period(row[3], (time_t)NULL) == 0) {
			zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (period)");
			continue;
		}

		alertid		= DBget_maxid("alerts", "alertid");
		sendto_esc	= DBdyn_escape_string_len(row[1], ALERT_SENDTO_LEN);

		DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock"
				",mediatypeid,sendto,subject,message,status,alerttype,esc_step)"
				" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d"
				"," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)",
				alertid,
				action->actionid,
				event->eventid,
				userid,
				now,
				mediatypeid,
				sendto_esc,
				subject_esc,
				message_esc,
				ALERT_STATUS_NOT_SENT,
				ALERT_TYPE_MESSAGE,
				escalation->esc_step);

		zbx_free(sendto_esc);
	}

	DBfree_result(result);

	if (0 == medias) {
		zbx_snprintf(error, sizeof(error), "No media defined for user \"%s\"",
				zbx_user_string(userid));

		alertid		= DBget_maxid("alerts", "alertid");
		error_esc	= DBdyn_escape_string(error);

		DBexecute("insert into alerts (alertid,actionid,eventid,userid,retries,clock"
				",subject,message,status,alerttype,error,esc_step)"
				" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d"
				",'%s','%s',%d,%d,'%s',%d)",
				alertid,
				action->actionid,
				event->eventid,
				userid,
				ALERT_MAX_RETRIES,
				now,
				subject_esc,
				message_esc,
				ALERT_STATUS_FAILED,
				ALERT_TYPE_MESSAGE,
				error_esc,
				escalation->esc_step);

		zbx_free(error_esc);
	}

	zbx_free(subject_esc);
	zbx_free(message_esc);
}
Ejemplo n.º 16
0
/******************************************************************************
 *                                                                            *
 * Function: update_items                                                     *
 *                                                                            *
 * Purpose: process record update                                             *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author:                                                                    *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	process_items(char **sql, size_t *sql_alloc, size_t *sql_offset, int sender_nodeid, int nodeid, const ZBX_TABLE *table,
		const char *record, int lastrecord)
{
	const char	*r;
	int		f, res = FAIL;
	zbx_uint64_t	itemid = 0;
	char		*value_esc;
	int		clock, value_type = -1;
	double		value_double;
	zbx_uint64_t	value_uint64;

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

	if (*sql_offset == 0)
		DBbegin_multiple_update(sql, sql_alloc, sql_offset);

	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "update items set prevvalue=lastvalue");

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

		if (NULL == r)
			goto error;

		zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER);

		if (0 == strcmp(table->fields[f].name, "itemid"))
			ZBX_STR2UINT64(itemid, buffer);

		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)
		{
			if (0 == strcmp(table->fields[f].name, "clock"))
			{
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, ",lastclock=%s", buffer);
				clock = atoi(buffer);
			}
			else if (0 == strcmp(table->fields[f].name, "value"))
			{
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, ",lastvalue=%s", buffer);

				value_type = table->fields[f].type;
				if (value_type == ZBX_TYPE_FLOAT)
					value_double = atof(buffer);
				else if (value_type == ZBX_TYPE_UINT)
					ZBX_STR2UINT64(value_uint64, buffer);
			}
		}
		else	/* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */
		{
			if (0 == strcmp(table->fields[f].name, "value"))
			{
				zbx_hex2binary(buffer);
				value_esc = DBdyn_escape_string_len(buffer, ITEM_LASTVALUE_LEN);
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, ",lastvalue='%s'", value_esc);
				zbx_free(value_esc);
			}
		}
	}

	if (value_type == ZBX_TYPE_FLOAT)
		DBadd_trend(itemid, value_double, clock);
	else if (value_type == ZBX_TYPE_UINT)
		DBadd_trend_uint(itemid, value_uint64, clock);

	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, " where itemid=" ZBX_FS_UI64 ";\n", itemid);

	if (lastrecord || *sql_offset > ZBX_MAX_SQL_SIZE)
	{
		DBend_multiple_update(sql, sql_alloc, sql_offset);

		if (DBexecute("%s", *sql) >= ZBX_DB_OK)
			res = SUCCEED;
		*sql_offset = 0;
	}
	else
		res = SUCCEED;

	return res;
error:
	zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received invalid record from node %d for node %d [%s]",
		CONFIG_NODEID, sender_nodeid, nodeid, record);

	return FAIL;
}
Ejemplo n.º 17
0
/******************************************************************************
 *                                                                            *
 * Function: lld_process_discovery_rule                                       *
 *                                                                            *
 * Purpose: add or update items, triggers and graphs for discovery item       *
 *                                                                            *
 * Parameters: lld_ruleid - [IN] discovery item identificator from database   *
 *             value      - [IN] received value from agent                    *
 *                                                                            *
 ******************************************************************************/
void	lld_process_discovery_rule(zbx_uint64_t lld_ruleid, char *value, zbx_timespec_t *ts)
{
	const char		*__function_name = "lld_process_discovery_rule";

	DB_RESULT		result;
	DB_ROW			row;
	zbx_uint64_t		hostid = 0;
	char			*discovery_key = NULL, *filter = NULL, *error = NULL, *db_error = NULL, *error_esc;
	unsigned char		state = 0;
	unsigned short		lifetime;
	zbx_vector_ptr_t	lld_rows;
	char			*sql = NULL;
	size_t			sql_alloc = 128, sql_offset = 0;
	const char		*sql_start = "update items set ", *sql_continue = ",";

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() itemid:" ZBX_FS_UI64, __function_name, lld_ruleid);

	zbx_vector_ptr_create(&lld_rows);
	sql = zbx_malloc(sql, sql_alloc);

	result = DBselect(
			"select hostid,key_,state,filter,error,lifetime"
			" from items"
			" where itemid=" ZBX_FS_UI64,
			lld_ruleid);

	if (NULL != (row = DBfetch(result)))
	{
		char	*lifetime_str;

		ZBX_STR2UINT64(hostid, row[0]);
		discovery_key = zbx_strdup(discovery_key, row[1]);
		state = (unsigned char)atoi(row[2]);
		filter = zbx_strdup(filter, row[3]);
		db_error = zbx_strdup(db_error, row[4]);

		lifetime_str = zbx_strdup(NULL, row[5]);
		substitute_simple_macros(NULL, NULL, NULL, NULL, &hostid, NULL, NULL,
				&lifetime_str, MACRO_TYPE_COMMON, NULL, 0);
		if (SUCCEED != is_ushort(lifetime_str, &lifetime))
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot process lost resources for the discovery rule \"%s:%s\":"
					" \"%s\" is not a valid value",
					zbx_host_string(hostid), discovery_key, lifetime_str);
			lifetime = 3650;	/* max value for the field */
		}
		zbx_free(lifetime_str);
	}
	else
		zabbix_log(LOG_LEVEL_WARNING, "invalid discovery rule ID [" ZBX_FS_UI64 "]", lld_ruleid);
	DBfree_result(result);

	if (0 == hostid)
		goto clean;

	if (SUCCEED != lld_rows_get(value, filter, &lld_rows, &error))
		goto error;

	error = zbx_strdup(error, "");

	lld_update_items(hostid, lld_ruleid, &lld_rows, &error, lifetime, ts->sec);
	lld_update_triggers(hostid, lld_ruleid, &lld_rows, &error);
	lld_update_graphs(hostid, lld_ruleid, &lld_rows, &error);
	lld_update_hosts(lld_ruleid, &lld_rows, &error, lifetime, ts->sec);

	if (ITEM_STATE_NOTSUPPORTED == state)
	{
		zabbix_log(LOG_LEVEL_WARNING,  "discovery rule [" ZBX_FS_UI64 "][%s] became supported",
				lld_ruleid, zbx_host_key_string(lld_ruleid));

		add_event(0, EVENT_SOURCE_INTERNAL, EVENT_OBJECT_LLDRULE, lld_ruleid, ts, ITEM_STATE_NORMAL,
				NULL, NULL, 0, 0);
		process_events();

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sstate=%d", sql_start, ITEM_STATE_NORMAL);
		sql_start = sql_continue;
	}
error:
	if (NULL != error && 0 != strcmp(error, db_error))
	{
		error_esc = DBdyn_escape_string_len(error, ITEM_ERROR_LEN);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%serror='%s'", sql_start, error_esc);
		sql_start = sql_continue;

		zbx_free(error_esc);
	}

	if (sql_start == sql_continue)
	{
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where itemid=" ZBX_FS_UI64, lld_ruleid);

		DBbegin();

		DBexecute("%s", sql);

		DBcommit();
	}
clean:
	zbx_free(error);
	zbx_free(db_error);
	zbx_free(filter);
	zbx_free(discovery_key);
	zbx_free(sql);

	zbx_vector_ptr_clean(&lld_rows, (zbx_mem_free_func_t)lld_row_free);
	zbx_vector_ptr_destroy(&lld_rows);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Ejemplo n.º 18
0
/******************************************************************************
 *                                                                            *
 * Function: process_httptest                                                 *
 *                                                                            *
 * Purpose: process single scenario of http test                              *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_httptest(DB_HTTPTEST *httptest)
{
	const char	*__function_name = "process_httptest";

	DB_RESULT	result;
	DB_ROW		row;
	DB_HTTPSTEP	httpstep;

	char		*err_str = NULL, *err_str_esc = NULL;
	int		now, lastfailedstep;

	ZBX_HTTPSTAT	stat;
	double		speed_download = 0;
	int		speed_download_num = 0;

#ifdef HAVE_LIBCURL
	int		err, opt;
	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->httptestid, httptest->name);

	lastfailedstep = 0;
	httptest->time = 0;

	now = time(NULL);

	DBexecute("update httptest"
			" set lastcheck=%d"
			" where httptestid=" ZBX_FS_UI64,
			now, httptest->httptestid);

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

#ifdef HAVE_LIBCURL

	if (NULL == (easyhandle = curl_easy_init()))
	{
		zabbix_log(LOG_LEVEL_ERR, "Web scenario [%s] error: could not init cURL library", httptest->name);
		err_str = zbx_strdup(err_str, "could not init cURL library");
		goto clean;
	}

	if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_COOKIEFILE, "")) ||
			CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_USERAGENT, httptest->agent)) ||
			CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_FOLLOWLOCATION, 1)) ||
			CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_WRITEFUNCTION, WRITEFUNCTION2)) ||
			CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HEADERFUNCTION, HEADERFUNCTION2)) ||
			CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYPEER, 0)) ||
			CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYHOST, 0)) ||
			/* The pointed data are not copied by the library. As a consequence, the data */
			/* must be preserved by the calling application until the transfer finishes. */
			CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, httpstep.posts)))
	{
		zabbix_log(LOG_LEVEL_ERR, "Web scenario [%s] error: could not set cURL option [%d]: %s",
				httptest->name, opt, curl_easy_strerror(err));
		err_str = zbx_strdup(err_str, curl_easy_strerror(err));
		goto clean;
	}

	while (NULL == err_str && NULL != (row = DBfetch(result)))
	{
		/* NOTE: do not use break or return for this block!
		 *       process_step_data calling required!
		 */
		ZBX_STR2UINT64(httpstep.httpstepid, row[0]);
		httpstep.httptestid = httptest->httptestid;
		httpstep.no = atoi(row[1]);
		httpstep.name = row[2];
		strscpy(httpstep.url, row[3]);
		httpstep.timeout = atoi(row[4]);
		strscpy(httpstep.posts, row[5]);
		strscpy(httpstep.required, row[6]);
		strscpy(httpstep.status_codes, row[7]);

		DBexecute("update httptest"
				" set curstep=%d,"
					"curstate=%d"
				" where httptestid=" ZBX_FS_UI64,
				httpstep.no,
				HTTPTEST_STATE_BUSY,
				httptest->httptestid);

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

		/* Substitute macros */
		http_substitute_macros(httptest, httpstep.url, sizeof(httpstep.url));
		http_substitute_macros(httptest, httpstep.posts, sizeof(httpstep.posts));

		zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: use step [%s]", httpstep.name);

		if ('\0' != *httpstep.posts)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: use post [%s]", httpstep.posts);
			curl_easy_setopt(easyhandle, CURLOPT_POST, 1);
		}
		else
			curl_easy_setopt(easyhandle, CURLOPT_POST, 0);

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

			zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: Setting HTTPAUTH [%d]", httptest->authentication);
			zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: Setting USERPWD for authentication");

			switch (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->http_user, httptest->http_password);

			if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HTTPAUTH, curlauth)) ||
					CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_USERPWD, auth)))
			{
				zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: could not set cURL option [%d]: %s",
						httptest->name, httpstep.name, opt, curl_easy_strerror(err));
				err_str = zbx_strdup(err_str, curl_easy_strerror(err));
			}
		}

		if (NULL == err_str)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: go to URL [%s]", httpstep.url);

			if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_URL, httpstep.url)) ||
					CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_TIMEOUT, httpstep.timeout)) ||
					CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_CONNECTTIMEOUT, httpstep.timeout)))
			{
				zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: could not set cURL option [%d]: %s",
						httptest->name, httpstep.name, opt, curl_easy_strerror(err));
				err_str = zbx_strdup(err_str, curl_easy_strerror(err));
			}
		}

		if (NULL == err_str)
		{
			memset(&page, 0, sizeof(page));

			if (CURLE_OK != (err = curl_easy_perform(easyhandle)))
			{
				zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error doing curl_easy_perform: %s",
						httptest->name, httpstep.name, curl_easy_strerror(err));
				err_str = zbx_strdup(err_str, curl_easy_strerror(err));
			}
			else
			{
				if ('\0' != httpstep.required[0] && NULL == zbx_regexp_match(page.data, httpstep.required, NULL))
				{
					zabbix_log(LOG_LEVEL_DEBUG, "Page did not match [%s]", httpstep.required);
					err_str = zbx_strdup(err_str, "Page did not match");
				}

				if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_RESPONSE_CODE, &stat.rspcode)))
				{
					zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error getting CURLINFO_RESPONSE_CODE: %s",
							httptest->name, httpstep.name, curl_easy_strerror(err));
					err_str = (NULL == err_str ? zbx_strdup(err_str, curl_easy_strerror(err)) : err_str);
				}
				else if ('\0' != httpstep.status_codes[0] && FAIL == int_in_list(httpstep.status_codes, stat.rspcode))
				{
					zabbix_log(LOG_LEVEL_DEBUG, "Status code did not match [%s]", httpstep.status_codes);
					err_str = (NULL == err_str ? zbx_strdup(err_str, "Status code did not match") : err_str);
				}

				if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_TOTAL_TIME, &stat.total_time)))
				{
					zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error getting CURLINFO_TOTAL_TIME: %s",
							httptest->name, httpstep.name, curl_easy_strerror(err));
					err_str = (NULL == err_str ? zbx_strdup(err_str, curl_easy_strerror(err)) : err_str);
				}

				if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_SPEED_DOWNLOAD, &stat.speed_download)))
				{
					zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error getting CURLINFO_SPEED_DOWNLOAD: %s",
							httptest->name, httpstep.name, curl_easy_strerror(err));
					err_str = (NULL == err_str ? zbx_strdup(err_str, curl_easy_strerror(err)) : err_str);
				}
				else
				{
					speed_download += stat.speed_download;
					speed_download_num++;
				}
			}

			zbx_free(page.data);
		}

		if (NULL != err_str)
			lastfailedstep = httpstep.no;

		httptest->time += stat.total_time;
		process_step_data(httpstep.httpstepid, &stat);
	}
clean:
	curl_easy_cleanup(easyhandle);
#else
	err_str = zbx_strdup(err_str, "cURL library is required for Web monitoring support");

#endif	/* HAVE_LIBCURL */

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

		lastfailedstep = 1;

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

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

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

	DBfree_result(result);

	err_str_esc = DBdyn_escape_string_len(err_str, HTTPTEST_ERROR_LEN);

	DBexecute("update httptest"
			" set curstep=0,"
				"curstate=%d,"
				"lastcheck=%d,"
				"nextcheck=%d+delay,"
				"lastfailedstep=%d,"
				"time=" ZBX_FS_DBL ","
				"error='%s'"
			" where httptestid=" ZBX_FS_UI64,
			HTTPTEST_STATE_IDLE,
			now, now,
			lastfailedstep,
			httptest->time,
			err_str_esc,
			httptest->httptestid);

	zbx_free(err_str_esc);
	zbx_free(err_str);

	stat.test_total_time = httptest->time;
	stat.test_last_step = lastfailedstep;
	stat.speed_download = speed_download_num ? speed_download / speed_download_num : 0;

	process_test_data(httptest->httptestid, &stat);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s() total_time:" ZBX_FS_DBL, __function_name, httptest->time);
}
Ejemplo n.º 19
0
/******************************************************************************
 *                                                                            *
 * Function: DCflush_nextchecks                                               *
 *                                                                            *
 * Purpose: add item nextcheck to the array                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Aleksander Vladishev                                               *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	DCflush_nextchecks()
{
	int			i, sql_offset = 0, sql_allocated = 1024;
	char			*sql = NULL;
	time_t			last_clock = -1;
	zbx_uint64_t		last_itemid = 0;
	char			*error_esc;

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

	if (nextcheck_num == 0)
		return;

	sql = zbx_malloc(sql, sql_allocated);

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n");
#endif

	for (i = 0; i < nextcheck_num; i++)
	{
		if (NULL != nextchecks[i].error_msg)
			continue;

		if (last_clock != nextchecks[i].clock) {
			if (last_clock != -1)
			{
				sql_offset--;
				zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4, ");\n");
			}

			if (last_itemid > nextchecks[i].itemid)
			{
#ifdef HAVE_ORACLE
				zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n");
#endif
				DBbegin();
				DBexecute("%s", sql);
				DBcommit();

				sql_offset = 0;
#ifdef HAVE_ORACLE
				zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n");
#endif
			}

			zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64,
					"update items set nextcheck=%d where itemid in (",
					(int)nextchecks[i].clock);
			last_clock = nextchecks[i].clock;
		}

		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 32, ZBX_FS_UI64 ",",
				nextchecks[i].itemid);
		last_itemid = nextchecks[i].itemid;
	}

	if (sql_offset > 8)
	{
		sql_offset--;
		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4, ");\n");
	}

	for (i = 0; i < nextcheck_num; i++)
	{
		if (NULL == nextchecks[i].error_msg) /* not supported items */
			continue;

		if (last_itemid > nextchecks[i].itemid)
		{
#ifdef HAVE_ORACLE
			zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n");
#endif
			DBbegin();
			DBexecute("%s", sql);
			DBcommit();

			sql_offset = 0;
#ifdef HAVE_ORACLE
			zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n");
#endif
		}

		error_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, ITEM_ERROR_LEN);
		zbx_free(nextchecks[i].error_msg);

		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_esc),
				"update items set status=%d,lastclock=%d,nextcheck=%d,error='%s'"
				" where itemid=" ZBX_FS_UI64 ";\n",
				ITEM_STATUS_NOTSUPPORTED,
				(int)nextchecks[i].clock,
				(int)(nextchecks[i].clock + CONFIG_REFRESH_UNSUPPORTED),
				error_esc,
				nextchecks[i].itemid);
		last_itemid = nextchecks[i].itemid;

		zbx_free(error_esc);
	}

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n");
#endif

	if (sql_offset > 16)
	{
		DBbegin();
		DBexecute("%s", sql);
		DBcommit();
	}

	zbx_free(sql);
}
Ejemplo n.º 20
0
/******************************************************************************
 *                                                                            *
 * Function: main_alerter_loop                                                *
 *                                                                            *
 * Purpose: periodically check table alerts and send notifications if needed  *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: never returns                                                    *
 *                                                                            *
 ******************************************************************************/
int main_alerter_loop()
{
	char			error[MAX_STRING_LEN], *error_esc;
	int			res, now;
	struct	sigaction	phan;
	DB_RESULT		result;
	DB_ROW			row;
	DB_ALERT		alert;
	DB_MEDIATYPE		mediatype;

/*	phan.sa_handler = child_signal_handler;*/
        phan.sa_sigaction = child_signal_handler;
	sigemptyset(&phan.sa_mask);
	phan.sa_flags = SA_SIGINFO;
	sigaction(SIGALRM, &phan, NULL);

	zbx_setproctitle("connecting to the database");

	DBconnect(ZBX_DB_CONNECT_NORMAL);

	for (;;) {
		now = time(NULL);

		result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid"
				",mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path"
				",mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt"
				" where a.status=%d and a.mediatypeid=mt.mediatypeid and a.alerttype=%d" DB_NODE
				" order by a.clock",
				ALERT_STATUS_NOT_SENT,
				ALERT_TYPE_MESSAGE,
				DBnode_local("mt.mediatypeid"));

		while (NULL != (row = DBfetch(result))) {
			res = FAIL;

			ZBX_STR2UINT64(alert.alertid, row[0]);
			alert.mediatypeid	= atoi(row[1]);
			alert.sendto		= row[2];
			alert.subject		= row[3];
			alert.message		= row[4];
			alert.status		= atoi(row[5]);

			ZBX_STR2UINT64(mediatype.mediatypeid, row[6]);
			mediatype.type		= atoi(row[7]);
			mediatype.description	= row[8];
			mediatype.smtp_server	= row[9];
			mediatype.smtp_helo	= row[10];
			mediatype.smtp_email	= row[11];
			mediatype.exec_path	= row[12];

			mediatype.gsm_modem	= row[13];
			mediatype.username	= row[14];
			mediatype.passwd	= row[15];

			alert.retries		= atoi(row[16]);

			*error = '\0';
			res = execute_action(&alert, &mediatype, error, sizeof(error));

			if (res == SUCCEED)
			{
				zabbix_log( LOG_LEVEL_DEBUG, "Alert ID [" ZBX_FS_UI64 "] was sent successfully",
					alert.alertid);
				DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64,
					ALERT_STATUS_SENT,
					alert.alertid);
			}
			else
			{
				zabbix_log( LOG_LEVEL_DEBUG, "Error sending alert ID [" ZBX_FS_UI64 "]",
					alert.alertid);
				zabbix_syslog("Error sending alert ID [" ZBX_FS_UI64 "]",
					alert.alertid);
				error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN);

				alert.retries++;
				if(alert.retries < ALERT_MAX_RETRIES)
				{
					DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
						alert.retries,
						error_esc,
						alert.alertid);
				}
				else
				{
					DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
						ALERT_STATUS_FAILED,
						alert.retries,
						error_esc,
						alert.alertid);
				}

				zbx_free(error_esc);
			}

		}
		DBfree_result(result);

		zbx_setproctitle("sender [sleeping for %d seconds]",
				CONFIG_SENDER_FREQUENCY);

		sleep(CONFIG_SENDER_FREQUENCY);
	}

	/* Never reached */
	DBclose();
}
Ejemplo n.º 21
0
/******************************************************************************
 *                                                                            *
 * Function: update_item                                                      *
 *                                                                            *
 * Purpose: update item info after new value is received                      *
 *                                                                            *
 * Parameters: item - item data                                               *
 *             value - new value of the item                                  *
 *             now   - current timestamp                                      * 
 *                                                                            *
 * Author: Alexei Vladishev, Eugene Grigorjev                                 *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	update_item(DB_ITEM *item, AGENT_RESULT *value, time_t now)
{
	char		*value_esc;
	zbx_uint64_t	value_uint64;
	double		value_double;

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

	item->nextcheck	= calculate_item_nextcheck(item->itemid, item->type, item->delay, item->delay_flex, now);

	switch (item->value_type) {
	case ITEM_VALUE_TYPE_FLOAT:
		if (NULL == GET_DBL_RESULT(value))
			break;

		switch (item->delta) {			/* Should we store delta or original value? */
		case ITEM_STORE_AS_IS:
			value_double = DBmultiply_value_float(item, value->dbl);
			DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue=NULL,"
					"lastvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64,
					item->nextcheck,
					value_double,
					(int)now,
					item->itemid);
			SET_DBL_RESULT(value, value_double);
			break;
		case ITEM_STORE_SPEED_PER_SECOND:	/* Delta as speed of change */
			if (0 == item->prevorgvalue_null && item->prevorgvalue_dbl <= value->dbl)
			{
				/* In order to continue normal processing, we assume difference 1 second
				   Otherwise function update_functions and update_triggers won't work correctly*/
				if (now != item->lastclock)
					value_double = (value->dbl - item->prevorgvalue_dbl) / (now - item->lastclock);
				else
					value_double = value->dbl - item->prevorgvalue_dbl;

				value_double = DBmultiply_value_float(item, value_double);
				DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_DBL "',"
						"lastvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->dbl,
						value_double,
						(int)now,
						item->itemid);
				SET_DBL_RESULT(value, value_double);
			}
			else
			{
				DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->dbl,
						(int)now,
						item->itemid);
			}
			break;
		case ITEM_STORE_SIMPLE_CHANGE:		/* Real delta: simple difference between values */
			if (0 == item->prevorgvalue_null && item->prevorgvalue_dbl <= value->dbl)
			{
				value_double = DBmultiply_value_float(item, value->dbl - item->prevorgvalue_dbl);
				DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_DBL "',"
						"lastvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->dbl,
						value_double,
						(int)now,
						item->itemid);
				SET_DBL_RESULT(value, value_double);
			}
			else
			{
				DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->dbl,
						(int)now,
						item->itemid);
			}
			break;
		}
		break;
	case ITEM_VALUE_TYPE_UINT64:
		if (NULL == GET_UI64_RESULT(value))
			break;

		switch (item->delta) {			/* Should we store delta or original value? */
		case ITEM_STORE_AS_IS:
			value_uint64 = DBmultiply_value_uint64(item, value->ui64);
			DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue=NULL,"
					"lastvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64,
					item->nextcheck,
					value_uint64,
					(int)now,
					item->itemid);
			SET_UI64_RESULT(value, value_uint64);
			break;
		case ITEM_STORE_SPEED_PER_SECOND:	/* Delta as speed of change */
			if (0 == item->prevorgvalue_null && item->prevorgvalue_uint64 <= value->ui64)
			{
				if (now != item->lastclock)
					value_uint64 = (zbx_uint64_t)(value->ui64 - item->prevorgvalue_uint64) / (now - item->lastclock);
				else
					value_uint64 = value->ui64 - item->prevorgvalue_uint64;

				value_uint64 = DBmultiply_value_uint64(item, value_uint64);
				DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_UI64 "',"
						"lastvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->ui64,
						value_uint64,
						(int)now,
						item->itemid);
				SET_UI64_RESULT(value, value_uint64);
			}
			else
			{
				DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->ui64,
						(int)now,
						item->itemid);
			}
			break;
		case ITEM_STORE_SIMPLE_CHANGE:		/* Real delta: simple difference between values */
			if (0 == item->prevorgvalue_null && item->prevorgvalue_uint64 <= value->ui64)
			{
				value_uint64 = DBmultiply_value_uint64(item, value->ui64 - item->prevorgvalue_uint64);
				DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_UI64 "',"
						"lastvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->ui64,
						value_uint64,
						(int)now,
						item->itemid);
				SET_UI64_RESULT(value, value_uint64);
			}
			else
			{
				DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64,
						item->nextcheck,
						value->ui64,
						(int)now,
						item->itemid);
			}
			break;
		}
		break;
	case ITEM_VALUE_TYPE_STR:
	case ITEM_VALUE_TYPE_TEXT:
		if (NULL == GET_STR_RESULT(value))
			break;

		value_esc = DBdyn_escape_string_len(value->str, ITEM_LASTVALUE_LEN);
		DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,lastvalue='%s',lastclock=%d"
				" where itemid=" ZBX_FS_UI64,
				item->nextcheck,
				value_esc,
				(int)now,
				item->itemid);
		zbx_free(value_esc);
		break;
	case ITEM_VALUE_TYPE_LOG:
		if (NULL == GET_STR_RESULT(value))
			break;

		value_esc = DBdyn_escape_string_len(value->str, ITEM_LASTVALUE_LEN);
		DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,lastvalue='%s',lastclock=%d,lastlogsize=%d"
				" where itemid=" ZBX_FS_UI64,
				item->nextcheck,
				value_esc,
				(int)now,
				item->lastlogsize,
				item->itemid);
		zbx_free(value_esc);
		break;
	}

	item->prevvalue_str	= item->lastvalue_str;
	item->prevvalue_dbl	= item->lastvalue_dbl;
	item->prevvalue_uint64	= item->lastvalue_uint64;
	item->prevvalue_null	= item->lastvalue_null;

	item->lastvalue_uint64	= value->ui64;
	item->lastvalue_dbl	= value->dbl;
	item->lastvalue_str	= value->str;
	item->lastvalue_null	= 0;

	/* Required for nodata() */
	item->lastclock		= now;

	/* Update item status if required */
	if (item->status == ITEM_STATUS_NOTSUPPORTED)
	{
		zabbix_log( LOG_LEVEL_WARNING, "Parameter [%s] became supported by agent on host [%s]",
			item->key,
			item->host_name);
		zabbix_syslog("Parameter [%s] became supported by agent on host [%s]",
			item->key,
			item->host_name);

		item->status = ITEM_STATUS_ACTIVE;
		DBexecute("update items set status=%d,error='' where itemid=" ZBX_FS_UI64,
				item->status,
				item->itemid);
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of update_item()");
}
Ejemplo n.º 22
0
static int	dm_rename_slave_data(const char *table_name, const char *key_name, const char *field_name,
		int field_length)
{
	DB_RESULT	result;
	DB_ROW		row;
	int		local_nodeid = 0, nodeid, globalmacro;
	zbx_uint64_t	id, min, max;
	char		*name = NULL, *name_esc;
	size_t		name_alloc = 0, name_offset;

	/* 1 - ZBX_NODE_LOCAL */
	if (NULL == (result = DBselect("select nodeid from nodes where nodetype=1")))
		return FAIL;

	if (NULL != (row = DBfetch(result)))
		local_nodeid = atoi(row[0]);
	DBfree_result(result);

	if (0 == local_nodeid)
		return SUCCEED;

	globalmacro = (0 == strcmp(table_name, "globalmacro"));

	min = local_nodeid * __UINT64_C(100000000000000);
	max = min + __UINT64_C(100000000000000) - 1;

	if (NULL == (result = DBselect(
			"select %s,%s"
			" from %s"
			" where not %s between " ZBX_FS_UI64 " and " ZBX_FS_UI64
			" order by %s",
			key_name, field_name, table_name, key_name, min, max, key_name)))
	{
		return FAIL;
	}

	while (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(id, row[0]);
		nodeid = (int)(id / __UINT64_C(100000000000000));

		name_offset = 0;

		if (0 == globalmacro)
			zbx_snprintf_alloc(&name, &name_alloc, &name_offset, "N%d_%s", nodeid, row[1]);
		else
			zbx_snprintf_alloc(&name, &name_alloc, &name_offset, "{$N%d_%s", nodeid, row[1] + 2);

		name_esc = DBdyn_escape_string_len(name, field_length);

		if (ZBX_DB_OK > DBexecute("update %s set %s='%s' where %s=" ZBX_FS_UI64,
				table_name, field_name, name_esc, key_name, id))
		{
			zbx_free(name_esc);
			break;
		}

		zbx_free(name_esc);
	}
	DBfree_result(result);

	zbx_free(name);

	return SUCCEED;
}
Ejemplo n.º 23
0
static void	deactivate_host(DC_ITEM *item, int now, const char *error)
{
	char		sql[MAX_STRING_LEN], *error_esc, error_msg[MAX_STRING_LEN];
	int		offset = 0, *errors_from, *disable_until;
	unsigned char	*available;
	const char	*fld_errors_from, *fld_available, *fld_disable_until, *fld_error, *type;

	switch (item->type)
	{
		case ITEM_TYPE_ZABBIX:
			errors_from = &item->host.errors_from;
			available = &item->host.available;
			disable_until = &item->host.disable_until;

			fld_errors_from = "errors_from";
			fld_available = "available";
			fld_disable_until = "disable_until";
			fld_error = "error";
			type = "Zabbix";
			break;
		case ITEM_TYPE_SNMPv1:
		case ITEM_TYPE_SNMPv2c:
		case ITEM_TYPE_SNMPv3:
			errors_from = &item->host.snmp_errors_from;
			available = &item->host.snmp_available;
			disable_until = &item->host.snmp_disable_until;

			fld_errors_from = "snmp_errors_from";
			fld_available = "snmp_available";
			fld_disable_until = "snmp_disable_until";
			fld_error = "snmp_error";
			type = "SNMP";
			break;
		case ITEM_TYPE_IPMI:
			errors_from = &item->host.ipmi_errors_from;
			available = &item->host.ipmi_available;
			disable_until = &item->host.ipmi_disable_until;

			fld_errors_from = "ipmi_errors_from";
			fld_available = "ipmi_available";
			fld_disable_until = "ipmi_disable_until";
			fld_error = "ipmi_error";
			type = "IPMI";
			break;
		default:
			return;
	}

	if (SUCCEED != DCconfig_deactivate_host(item, now))
		return;

	DBbegin();

	*error_msg = '\0';

	offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "update hosts set ");

	/* First error */
	if (0 == *errors_from)
	{
		zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: first network error, wait for %d seconds",
				type, item->host.host, CONFIG_UNREACHABLE_DELAY);

		*errors_from = now;
		*disable_until = now + CONFIG_UNREACHABLE_DELAY;
		offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,",
				fld_errors_from, *errors_from);
	}
	else
	{
		if (now - *errors_from <= CONFIG_UNREACHABLE_PERIOD)
		{
			/* Still unavailable, but won't change status to UNAVAILABLE yet */
			zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: another network error, wait for %d seconds",
					type, item->host.host, CONFIG_UNREACHABLE_DELAY);

			*disable_until = now + CONFIG_UNREACHABLE_DELAY;
		}
		else
		{
			*disable_until = now + CONFIG_UNAVAILABLE_DELAY;

			if (HOST_AVAILABLE_FALSE != *available)
			{
				zbx_snprintf(error_msg, sizeof(error_msg), "Disabling %s host [%s]",
						type, item->host.host);

				*available = HOST_AVAILABLE_FALSE;

				offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,",
						fld_available, *available);

				if (available == &item->host.available)
					update_key_status(item->host.hostid, HOST_AVAILABLE_FALSE, now); /* 2 */

				update_triggers_status_to_unknown(item->host.hostid, item->type, now, "Agent is unavailable.");
			}

			error_esc = DBdyn_escape_string_len(error, HOST_ERROR_LEN);
			offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s='%s',",
					fld_error, error_esc);
			zbx_free(error_esc);
		}
	}

	offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d where hostid=" ZBX_FS_UI64,
			fld_disable_until, *disable_until, item->host.hostid);

	DBexecute("%s", sql);
	DBcommit();

	if ('\0' != *error_msg)
	{
		zabbix_log(LOG_LEVEL_WARNING, "%s", error_msg);
		zabbix_syslog("%s", error_msg);
	}
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
/******************************************************************************
 *                                                                            *
 * Function: main_alerter_loop                                                *
 *                                                                            *
 * Purpose: periodically check table alerts and send notifications if needed  *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
void	main_alerter_loop()
{
	char			error[MAX_STRING_LEN], *error_esc;
	int			res;
	DB_RESULT		result;
	DB_ROW			row;
	DB_ALERT		alert;
	DB_MEDIATYPE		mediatype;

	zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));

	DBconnect(ZBX_DB_CONNECT_NORMAL);

	for (;;)
	{
		zbx_setproctitle("%s [sending alerts]", get_process_type_string(process_type));

		result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid"
				",mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path"
				",mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt"
				" where a.status=%d and a.mediatypeid=mt.mediatypeid and a.alerttype=%d" DB_NODE
				" order by a.clock",
				ALERT_STATUS_NOT_SENT,
				ALERT_TYPE_MESSAGE,
				DBnode_local("mt.mediatypeid"));

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(alert.alertid, row[0]);
			alert.mediatypeid = atoi(row[1]);
			alert.sendto = row[2];
			alert.subject = row[3];
			alert.message = row[4];
			alert.status = atoi(row[5]);

			ZBX_STR2UINT64(mediatype.mediatypeid, row[6]);
			mediatype.type = atoi(row[7]);
			mediatype.description = row[8];
			mediatype.smtp_server = row[9];
			mediatype.smtp_helo = row[10];
			mediatype.smtp_email = row[11];
			mediatype.exec_path = row[12];
			mediatype.gsm_modem = row[13];
			mediatype.username = row[14];
			mediatype.passwd = row[15];

			alert.retries = atoi(row[16]);

			*error = '\0';
			res = execute_action(&alert, &mediatype, error, sizeof(error));

			if (SUCCEED == res)
			{
				zabbix_log(LOG_LEVEL_DEBUG, "Alert ID [" ZBX_FS_UI64 "] was sent successfully",
						alert.alertid);
				DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64,
						ALERT_STATUS_SENT, alert.alertid);
			}
			else
			{
				zabbix_log(LOG_LEVEL_DEBUG, "Error sending alert ID [" ZBX_FS_UI64 "]",
						alert.alertid);
				zabbix_syslog("Error sending alert ID [" ZBX_FS_UI64 "]",
						alert.alertid);

				error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN);

				alert.retries++;

				if (ALERT_MAX_RETRIES > alert.retries)
				{
					DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
							alert.retries, error_esc, alert.alertid);
				}
				else
				{
					DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
							ALERT_STATUS_FAILED, alert.retries, error_esc, alert.alertid);
				}

				zbx_free(error_esc);
			}

		}
		DBfree_result(result);

		zbx_sleep_loop(CONFIG_SENDER_FREQUENCY);
	}
}
Ejemplo n.º 26
0
/******************************************************************************
 *                                                                            *
 * Function: update_functions                                                 *
 *                                                                            *
 * Purpose: re-calculate and updates values of functions related to the item  *
 *                                                                            *
 * Parameters: item - item to update functions for                            *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	update_functions(DB_ITEM *item, time_t now)
{
	DB_FUNCTION	function;
	DB_RESULT	result;
	DB_ROW		row;
	char		value[MAX_STRING_LEN];
	char		*value_esc, *function_esc, *parameter_esc;
	char		*lastvalue;
	int		ret=SUCCEED;

	zabbix_log( LOG_LEVEL_DEBUG, "In update_functions(" ZBX_FS_UI64 ")",
		item->itemid);

/* Oracle does'n support this */
/*	zbx_snprintf(sql,sizeof(sql),"select function,parameter,itemid,lastvalue from functions where itemid=%d group by function,parameter,itemid order by function,parameter,itemid",item->itemid);*/
	result = DBselect("select distinct function,parameter,itemid,lastvalue from functions where itemid=" ZBX_FS_UI64,
		item->itemid);

	while((row=DBfetch(result)))
	{
		function.function=row[0];
		function.parameter=row[1];
		ZBX_STR2UINT64(function.itemid,row[2]);
/*		function.itemid=atoi(row[2]); */
/*		It is not required to check lastvalue for NULL here */
		lastvalue=row[3];

		zabbix_log( LOG_LEVEL_DEBUG, "ItemId:" ZBX_FS_UI64 " Evaluating %s(%s)",
			function.itemid,
			function.function,
			function.parameter);

		ret = evaluate_function(value, item, function.function, function.parameter, now);
		if( FAIL == ret)	
		{
			zabbix_log( LOG_LEVEL_DEBUG, "Evaluation failed for function:%s",
				function.function);
			continue;
		}
		if (ret == SUCCEED)
		{
			/* Update only if lastvalue differs from new one */
			if (DBis_null(lastvalue) == SUCCEED || 0 != strcmp(lastvalue, value))
			{
				value_esc = DBdyn_escape_string_len(value, FUNCTION_LASTVALUE_LEN);
				function_esc = DBdyn_escape_string(function.function);
				parameter_esc = DBdyn_escape_string(function.parameter);

				DBexecute("update functions set lastvalue='%s' where itemid=" ZBX_FS_UI64 " and function='%s' and parameter='%s'",
						value_esc,
						function.itemid,
						function_esc,
						parameter_esc);

				zbx_free(parameter_esc);
				zbx_free(function_esc);
				zbx_free(value_esc);
			}
			else
				zabbix_log( LOG_LEVEL_DEBUG, "Do not update functions, same value");
		}
	}

	DBfree_result(result);

	zabbix_log( LOG_LEVEL_DEBUG, "End update_functions()");
}
Ejemplo n.º 27
0
/******************************************************************************
 *                                                                            *
 * Function: discovery_register_service                                       *
 *                                                                            *
 * Purpose: register service if one does not exist                            *
 *                                                                            *
 * Parameters: host ip address                                                *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static void	discovery_register_service(DB_DRULE *drule, DB_DCHECK *dcheck,
		DB_DHOST *dhost, DB_DSERVICE *dservice, const char *ip, const char *dns,
		int port, int status, int now)
{
	const char	*__function_name = "discovery_register_service";

	DB_RESULT	result;
	DB_ROW		row;
	char		*key_esc, *ip_esc, *dns_esc;

	zbx_uint64_t	dhostid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() ip:'%s' port:%d key:'%s'",
			__function_name, ip, port, dcheck->key_);

	key_esc = DBdyn_escape_string_len(dcheck->key_, DSERVICE_KEY_LEN);
	ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN);

	result = DBselect(
			"select dserviceid,dhostid,status,lastup,lastdown,value,dns"
			" from dservices"
			" where dcheckid=" ZBX_FS_UI64
				" and type=%d"
				" and key_" ZBX_SQL_STRCMP
				" and ip" ZBX_SQL_STRCMP
				" and port=%d",
			dcheck->dcheckid,
			dcheck->type,
			ZBX_SQL_STRVAL_EQ(key_esc),
			ZBX_SQL_STRVAL_EQ(ip_esc),
			port);

	if (NULL == (row = DBfetch(result)))
	{
		if (DOBJECT_STATUS_UP == status)	/* add host only if service is up */
		{
			zabbix_log(LOG_LEVEL_DEBUG, "new service discovered on port %d", port);

			dservice->dserviceid = DBget_maxid("dservices");
			dservice->status = DOBJECT_STATUS_DOWN;

			dns_esc = DBdyn_escape_string_len(dns, INTERFACE_DNS_LEN);

			DBexecute("insert into dservices (dserviceid,dhostid,dcheckid,type,key_,ip,dns,port,status)"
					" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,'%s','%s','%s',%d,%d)",
					dservice->dserviceid, dhost->dhostid, dcheck->dcheckid, dcheck->type,
					key_esc, ip_esc, dns_esc, port, dservice->status);

			zbx_free(dns_esc);
		}
	}
	else
	{
		zabbix_log(LOG_LEVEL_DEBUG, "service is already in database");

		ZBX_STR2UINT64(dservice->dserviceid, row[0]);
		ZBX_STR2UINT64(dhostid, row[1]);
		dservice->status = atoi(row[2]);
		dservice->lastup = atoi(row[3]);
		dservice->lastdown = atoi(row[4]);
		strscpy(dservice->value, row[5]);

		if (dhostid != dhost->dhostid)
		{
			DBexecute("update dservices"
					" set dhostid=" ZBX_FS_UI64
					" where dhostid=" ZBX_FS_UI64,
					dhost->dhostid, dhostid);

			DBexecute("delete from dhosts"
					" where dhostid=" ZBX_FS_UI64,
					dhostid);
		}

		if (0 != strcmp(row[6], dns))
		{
			dns_esc = DBdyn_escape_string_len(dns, INTERFACE_DNS_LEN);

			DBexecute("update dservices"
					" set dns='%s'"
					" where dserviceid=" ZBX_FS_UI64,
					dns_esc, dservice->dserviceid);

			zbx_free(dns_esc);
		}
	}
	DBfree_result(result);

	zbx_free(ip_esc);
	zbx_free(key_esc);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Ejemplo n.º 28
0
/******************************************************************************
 *                                                                            *
 * Function: main_alerter_loop                                                *
 *                                                                            *
 * Purpose: periodically check table alerts and send notifications if needed  *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
ZBX_THREAD_ENTRY(alerter_thread, args)
{
	char		error[MAX_STRING_LEN], *error_esc;
	int		res, alerts_success, alerts_fail;
	double		sec;
	DB_RESULT	result;
	DB_ROW		row;
	DB_ALERT	alert;
	DB_MEDIATYPE	mediatype;

	process_type = ((zbx_thread_args_t *)args)->process_type;
	server_num = ((zbx_thread_args_t *)args)->server_num;
	process_num = ((zbx_thread_args_t *)args)->process_num;

	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type),
			server_num, get_process_type_string(process_type), process_num);

	zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));

	DBconnect(ZBX_DB_CONNECT_NORMAL);

	for (;;)
	{
		zbx_setproctitle("%s [sending alerts]", get_process_type_string(process_type));

		sec = zbx_time();

		alerts_success = alerts_fail = 0;

		result = DBselect(
				"select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid,"
					"mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path,"
					"mt.gsm_modem,mt.username,mt.passwd,mt.smtp_port,mt.smtp_security,"
					"mt.smtp_verify_peer,mt.smtp_verify_host,mt.smtp_authentication,a.retries"
				" from alerts a,media_type mt"
				" where a.mediatypeid=mt.mediatypeid"
					" and a.status=%d"
					" and a.alerttype=%d"
				" order by a.alertid",
				ALERT_STATUS_NOT_SENT,
				ALERT_TYPE_MESSAGE);

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(alert.alertid, row[0]);
			ZBX_STR2UINT64(alert.mediatypeid, row[1]);
			alert.sendto = row[2];
			alert.subject = row[3];
			alert.message = row[4];
			alert.status = atoi(row[5]);

			ZBX_STR2UINT64(mediatype.mediatypeid, row[6]);
			mediatype.type = atoi(row[7]);
			mediatype.description = row[8];
			mediatype.smtp_server = row[9];
			mediatype.smtp_helo = row[10];
			mediatype.smtp_email = row[11];
			mediatype.exec_path = row[12];
			mediatype.gsm_modem = row[13];
			mediatype.username = row[14];
			mediatype.passwd = row[15];
			mediatype.smtp_port = (unsigned short)atoi(row[16]);
			ZBX_STR2UCHAR(mediatype.smtp_security, row[17]);
			ZBX_STR2UCHAR(mediatype.smtp_verify_peer, row[18]);
			ZBX_STR2UCHAR(mediatype.smtp_verify_host, row[19]);
			ZBX_STR2UCHAR(mediatype.smtp_authentication, row[20]);

			alert.retries = atoi(row[21]);

			*error = '\0';
			res = execute_action(&alert, &mediatype, error, sizeof(error));

			if (SUCCEED == res)
			{
				zabbix_log(LOG_LEVEL_DEBUG, "alert ID [" ZBX_FS_UI64 "] was sent successfully",
						alert.alertid);
				DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64,
						ALERT_STATUS_SENT, alert.alertid);
				alerts_success++;
			}
			else
			{
				zabbix_log(LOG_LEVEL_DEBUG, "error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid);

				error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN);

				alert.retries++;

				if (ALERT_MAX_RETRIES > alert.retries)
				{
					DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
							alert.retries, error_esc, alert.alertid);
				}
				else
				{
					DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
							ALERT_STATUS_FAILED, alert.retries, error_esc, alert.alertid);
				}

				zbx_free(error_esc);

				alerts_fail++;
			}

		}
		DBfree_result(result);

		sec = zbx_time() - sec;

		zbx_setproctitle("%s [sent alerts: %d success, %d fail in " ZBX_FS_DBL " sec, idle %d sec]",
				get_process_type_string(process_type), alerts_success, alerts_fail, sec,
				CONFIG_SENDER_FREQUENCY);

		zbx_sleep_loop(CONFIG_SENDER_FREQUENCY);
	}
}