Exemplo n.º 1
0
/******************************************************************************
 *                                                                            *
 * Function: send_list_of_active_checks_json                                  *
 *                                                                            *
 * Purpose: send list of active checks to the host                            *
 *                                                                            *
 * Parameters: sock - open socket of server-agent connection                  *
 *             json - request buffer                                          *
 *                                                                            *
 * Return value:  SUCCEED - list of active checks sent successfully           *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	send_list_of_active_checks_json(zbx_sock_t *sock, struct zbx_json_parse *jp)
{
	const char	*__function_name = "send_list_of_active_checks_json";
	char		host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN],
			pattern[MAX_STRING_LEN], tmp[32],
			key_severity[MAX_STRING_LEN], key_logeventid[MAX_STRING_LEN],
			ip[INTERFACE_IP_LEN_MAX];
	DB_RESULT	result;
	DB_ROW		row;
	struct zbx_json	json;
	int		res = FAIL, refresh_unsupported, now;
	zbx_uint64_t	hostid;
	char		error[MAX_STRING_LEN], *key = NULL;
	DC_ITEM		dc_item;
	unsigned short	port;

	char		**regexp = NULL;
	int		regexp_alloc = 0;
	int		regexp_num = 0, n;

	char		*sql = NULL;
	size_t		sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0;

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

	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host)))
	{
		zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror());
		goto error;
	}

	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip)))
		strscpy(ip, get_ip_by_socket(sock));

	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, tmp, sizeof(tmp)))
		*tmp = '\0';

	if (FAIL == is_ushort(tmp, &port))
		port = ZBX_DEFAULT_AGENT_PORT;

	if (FAIL == get_hostid_by_host(host, ip, port, &hostid, error))
		goto error;

	DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED);

	now = time(NULL);

	sql = zbx_malloc(sql, sql_alloc);

	name_esc = DBdyn_escape_string(host);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select i.key_,i.delay,i.lastlogsize,i.mtime"
			" from items i,hosts h"
			" where i.hostid=h.hostid"
				" and h.status=%d"
				" and i.type=%d"
				" and i.flags<>%d"
				" and h.hostid=" ZBX_FS_UI64
				" and h.proxy_hostid is null",
			HOST_STATUS_MONITORED,
			ITEM_TYPE_ZABBIX_ACTIVE,
			ZBX_FLAG_DISCOVERY_CHILD,
			hostid);

	zbx_free(name_esc);

	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
	zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
	zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA);

	result = DBselect("%s", sql);

	while (NULL != (row = DBfetch(result)))
	{
		if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[0]))
		{
			zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was not found in the server cache. Not sending now.", __function_name, row[0]);
			continue;
		}

		if (ITEM_STATUS_NOTSUPPORTED == dc_item.status)
		{
			if (0 == refresh_unsupported || dc_item.lastclock + refresh_unsupported > now)
			{
				DCconfig_clean_items(&dc_item, NULL, 1);
				continue;
			}
		}

		zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was successfully found in the server cache. Sending.", __function_name, row[0]);

		ZBX_STRDUP(key, row[0]);
		substitute_key_macros(&key, NULL, &dc_item, NULL, MACRO_TYPE_ITEM_KEY, NULL, 0);

		DCconfig_clean_items(&dc_item, NULL, 1);

		zbx_json_addobject(&json, NULL);
		zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, key, ZBX_JSON_TYPE_STRING);
		if (0 != strcmp(key, row[0]))
			zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, row[0], ZBX_JSON_TYPE_STRING);
		zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, row[1], ZBX_JSON_TYPE_INT);
		/* The agent expects ALWAYS to have lastlogsize and mtime tags. Removing those would cause older agents to fail. */
		zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, row[2], ZBX_JSON_TYPE_INT);
		zbx_json_addstring(&json, ZBX_PROTO_TAG_MTIME, row[3], ZBX_JSON_TYPE_INT);
		zbx_json_close(&json);

		/* special processing for log[] and logrt[] items */
		do {	/* simple try realization */

			/* log[filename,pattern,encoding,maxlinespersec] */
			/* logrt[filename_format,pattern,encoding,maxlinespersec] */

			if (0 != strncmp(key, "log[", 4) && 0 != strncmp(key, "logrt[", 6))
				break;

			if (2 != parse_command(key, NULL, 0, params, sizeof(params)))
				break;

			/* dealing with `pattern' parameter */
			if (0 == get_param(params, 2, pattern, sizeof(pattern)) &&
				*pattern == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, pattern + 1);
		} while (0);	/* simple try realization */

		/* special processing for eventlog[] items */
		do {	/* simple try realization */

			/* eventlog[filename,pattern,severity,source,logeventid,maxlinespersec] */

			if (0 != strncmp(key, "eventlog[", 9))
				break;

			if (2 != parse_command(key, NULL, 0, params, sizeof(params)))
				break;

			/* dealing with `pattern' parameter */
			if (0 == get_param(params, 2, pattern, sizeof(pattern)) &&
				*pattern == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, pattern + 1);

			/* dealing with `severity' parameter */
			if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) &&
				*key_severity == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, key_severity + 1);

			/* dealing with `logeventid' parameter */
			if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) &&
				*key_logeventid == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, key_logeventid + 1);
		} while (0);	/* simple try realization */

		zbx_free(key);
	}
	zbx_json_close(&json);

	DBfree_result(result);

	if (0 != regexp_num)
	{
		zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP);

		sql_offset = 0;
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
				"select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive"
				" from regexps r,expressions e"
				" where r.regexpid=e.regexpid"
					" and r.name in (");

		for (n = 0; n < regexp_num; n++)
		{
			name_esc = DBdyn_escape_string(regexp[n]);
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s'%s'",
					n == 0 ? "" : ",",
					name_esc);
			zbx_free(name_esc);
			zbx_free(regexp[n]);
		}
		zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ')');

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, DB_NODE, DBnode_local("r.regexpid"));

		result = DBselect("%s", sql);
		while (NULL != (row = DBfetch(result)))
		{
			zbx_json_addobject(&json, NULL);
			zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING);
			zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING);
			zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT);
			zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING);
			zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT);
			zbx_json_close(&json);
		}
		DBfree_result(result);
	}
	zbx_free(regexp);

	zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer);

	alarm(CONFIG_TIMEOUT);
	if (SUCCEED != zbx_tcp_send(sock, json.buffer))
		strscpy(error, zbx_tcp_strerror());
	else
		res = SUCCEED;
	alarm(0);

	zbx_json_free(&json);
	zbx_free(sql);

	goto out;
error:
	zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), error);

	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
	zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING);
	zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING);

	zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer);

	res = zbx_tcp_send(sock, json.buffer);

	zbx_json_free(&json);
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res));

	return res;
}
Exemplo n.º 2
0
/******************************************************************************
 *                                                                            *
 * Function: send_list_of_active_checks_json                                  *
 *                                                                            *
 * Purpose: send list of active checks to the host                            *
 *                                                                            *
 * Parameters: sock - open socket of server-agent connection                  *
 *             json - request buffer                                          *
 *                                                                            *
 * Return value:  SUCCEED - list of active checks sent successfully           *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	send_list_of_active_checks_json(zbx_sock_t *sock, struct zbx_json_parse *jp)
{
	char		host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN],
			pattern[MAX_STRING_LEN], tmp[32],
			key_severity[MAX_STRING_LEN], key_logeventid[MAX_STRING_LEN];
	DB_RESULT	result;
	DB_ROW		row;
	DB_ITEM		item;
	struct zbx_json	json;
	int		res = FAIL;
	zbx_uint64_t	hostid;
	char		error[MAX_STRING_LEN];
	DC_ITEM		dc_item;

	char		**regexp = NULL;
	int		regexp_alloc = 0;
	int		regexp_num = 0, n;

	char		*sql = NULL;
	int		sql_alloc = 2048;
	int		sql_offset;

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

	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host)))
	{
		zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror());
		goto error;
	}

	if (FAIL == get_hostid_by_host(host, &hostid, error))
		goto error;

	sql = zbx_malloc(sql, sql_alloc);

	name_esc = DBdyn_escape_string(host);

	sql_offset = 0;
	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 1024,
			"select %s where i.hostid=h.hostid and h.status=%d and i.type=%d and h.hostid=" ZBX_FS_UI64
			" and h.proxy_hostid=0",
			ZBX_SQL_ITEM_SELECT,
			HOST_STATUS_MONITORED,
			ITEM_TYPE_ZABBIX_ACTIVE,
			hostid);

	if (0 != CONFIG_REFRESH_UNSUPPORTED)
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and (i.status=%d or (i.status=%d and i.lastclock+%d<=%d))",
				ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED,
				CONFIG_REFRESH_UNSUPPORTED, time(NULL));
	else
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and i.status=%d",
				ITEM_STATUS_ACTIVE);

	zbx_free(name_esc);

	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
	zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
	zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA);

	result = DBselect("%s", sql);

	while (NULL != (row = DBfetch(result)))
	{
		if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[1]))
		{
			zabbix_log(LOG_LEVEL_DEBUG, "Item '%s' was not found in the server cache. Not sending now.", row[1]);
			continue;
		}

		zabbix_log(LOG_LEVEL_DEBUG, "Item '%s' was successfully found in the server cache. Sending.", row[1]);

		DBget_item_from_db(&item, row);

		zbx_json_addobject(&json, NULL);
		zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, item.key, ZBX_JSON_TYPE_STRING);
		if (0 != strcmp(item.key, item.key_orig))
			zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, item.key_orig, ZBX_JSON_TYPE_STRING);
		zbx_snprintf(tmp, sizeof(tmp), "%d", item.delay);
		zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, tmp, ZBX_JSON_TYPE_STRING);
		/* The agent expects ALWAYS to have lastlogsize and mtime tags. Removing those would cause older agents to fail. */
		zbx_snprintf(tmp, sizeof(tmp), "%d", item.lastlogsize);
		zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, ZBX_JSON_TYPE_STRING);
		zbx_snprintf(tmp, sizeof(tmp), "%d", item.mtime);
		zbx_json_addstring(&json, ZBX_PROTO_TAG_MTIME, tmp, ZBX_JSON_TYPE_STRING);
		zbx_json_close(&json);

		/* Special processing for log[] and logrt[] items */
		do {	/* simple try realization */

			/* log[filename,pattern,encoding,maxlinespersec] */
			/* logrt[filename_format,pattern,encoding,maxlinespersec] */

			if (0 != strncmp(item.key, "log[", 4) && 0 != strncmp(item.key, "logrt[", 6))
				break;

			if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN))
				break;

			/*dealing with `pattern' parameter*/
			if (0 == get_param(params, 2, pattern, sizeof(pattern)) &&
				*pattern == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, pattern + 1);
		} while (0);	/* simple try realization */

		/* Special processing for eventlog[] items */
		do {	/* simple try realization */

			/* eventlog[filename,pattern,severity,source,logeventid,maxlinespersec] */

			if (0 != strncmp(item.key, "eventlog[", 9))
				break;

			if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN))
				break;

			/*dealing with `pattern' parameter*/
			if (0 == get_param(params, 2, pattern, sizeof(pattern)) &&
				*pattern == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, pattern + 1);

			/*dealing with `severity' parameter*/
			if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) &&
				*key_severity == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, key_severity + 1);

			/*dealing with `logeventid' parameter*/
			if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) &&
				*key_logeventid == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, key_logeventid + 1);
		} while (0);	/* simple try realization */
	}
	zbx_json_close(&json);

	DBfree_result(result);

	if (0 != regexp_num)
	{
		zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP);

		sql_offset = 0;
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512,
				"select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive"
				" from regexps r,expressions e where r.regexpid=e.regexpid and r.name in (");

		for (n = 0; n < regexp_num; n++)
		{
			name_esc = DBdyn_escape_string(regexp[n]);
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "%s'%s'",
					n == 0 ? "" : ",",
					name_esc);
			zbx_free(name_esc);
			zbx_free(regexp[n]);
		}
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, ")");

		result = DBselect("%s", sql);
		while (NULL != (row = DBfetch(result)))
		{
			zbx_json_addobject(&json, NULL);
			zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING);
			zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING);
			zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT);
			zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING);
			zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT);
			zbx_json_close(&json);
		}
		DBfree_result(result);
	}
	zbx_free(regexp);

	zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]",
			json.buffer);

	alarm(CONFIG_TIMEOUT);
	if (SUCCEED != zbx_tcp_send(sock, json.buffer))
		zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror());
	else
		res = SUCCEED;
	alarm(0);

	zbx_json_free(&json);
	zbx_free(sql);

	return res;
error:
	//zabbix_log(LOG_LEVEL_WARNING, "Sending list of active checks to [%s] failed: %s",
	//			get_ip_by_socket(sock), error);

	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
	zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING);
	zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING);

	zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]",
			json.buffer);

	res = zbx_tcp_send(sock, json.buffer);

	zbx_json_free(&json);

	return res;
}