/****************************************************************************** * * * 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 succesfully * * FAIL - an error occured * * * * Author: Aleksander 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]; 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]; char **regexp = NULL; int regexp_alloc = 32; 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 out; } if (FAIL == get_hostid_by_host(host, &hostid, error)) goto out; regexp = zbx_malloc(regexp, regexp_alloc); 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.nextcheck<=%d))", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, 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))) { 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); zbx_snprintf(tmp, sizeof(tmp), "%d", item.lastlogsize); zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, ZBX_JSON_TYPE_STRING); zbx_json_close(&json); /* Special processing for log[] and eventlog[] items */ do { /* simple try realization */ if (0 != strncmp(item.key, "log[", 4) && 0 != strncmp(item.key, "eventlog[", 9)) break; if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN)) break;; if (0 != get_param(params, 2, pattern, sizeof(pattern))) break; if (*pattern != '@') break; for (n = 0; n < regexp_num; n++) if (0 == strcmp(regexp[n], pattern + 1)) break; if (n != regexp_num) break; if (regexp_num == regexp_alloc) { regexp_alloc += 32; regexp = zbx_realloc(regexp, regexp_alloc); } regexp[regexp_num++] = strdup(pattern + 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); if (SUCCEED != zbx_tcp_send_raw(sock, json.buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; zbx_json_free(&json); zbx_free(sql); out: if (FAIL == res) zabbix_log(LOG_LEVEL_WARNING, "Send list of active checks to [%s] failed: %s", get_ip_by_socket(sock), error); return res; }
/****************************************************************************** * * * Function: send_list_of_active_checks * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * request - request buffer * * * * Return value: SUCCEED - list of active checks sent succesfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n * * format of the list: key:delay:last_log_size * * * ******************************************************************************/ int send_list_of_active_checks(zbx_sock_t *sock, char *request) { char *host = NULL, *p; DB_RESULT result; DB_ROW row; char *buffer = NULL; int buffer_alloc = 2048; int buffer_offset = 0; int res = FAIL; zbx_uint64_t hostid; char error[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In send_list_of_active_checks()"); if (NULL != (host = strchr(request, '\n'))) { host++; if (NULL != (p = strchr(host, '\n'))) *p = '\0'; } else { zbx_snprintf(error, MAX_STRING_LEN, "host is null"); goto out; } if (FAIL == get_hostid_by_host(host, &hostid, error)) goto out; buffer = zbx_malloc(buffer, buffer_alloc); buffer_offset = 0; zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 1024, "select i.key_,i.delay,i.lastlogsize from items i,hosts h" " where i.hostid=h.hostid and h.status=%d and i.type=%d and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid=0", HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, hostid); if (0 != CONFIG_REFRESH_UNSUPPORTED) { zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 256, " and (i.status=%d or (i.status=%d and i.nextcheck<=%d))", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, time(NULL)); } else { zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 256, " and i.status=%d", ITEM_STATUS_ACTIVE); } result = DBselect("%s", buffer); buffer_offset = 0; while (NULL != (row = DBfetch(result))) { zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 512, "%s:%s:%s\n", row[0], row[1], row[2]); } DBfree_result(result); zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, 512, "ZBX_EOF\n"); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", buffer); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; zbx_free(buffer); out: if (FAIL == res) zabbix_log(LOG_LEVEL_WARNING, "Send list of active checks to [%s] failed: %s", get_ip_by_socket(sock), error); return res; }
/****************************************************************************** * * * 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(®exp, ®exp_alloc, ®exp_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(®exp, ®exp_alloc, ®exp_num, pattern + 1); /* dealing with `severity' parameter */ if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) && *key_severity == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_severity + 1); /* dealing with `logeventid' parameter */ if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) && *key_logeventid == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_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; }
/****************************************************************************** * * * Function: send_list_of_active_checks * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * request - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n * * format of the list: key:delay:last_log_size * * * ******************************************************************************/ int send_list_of_active_checks(zbx_sock_t *sock, char *request) { const char *__function_name = "send_list_of_active_checks"; char *host = NULL, *p; DB_RESULT result; DB_ROW row; char *buffer = NULL; size_t buffer_alloc = 2 * ZBX_KIBIBYTE, buffer_offset = 0; int res = FAIL, refresh_unsupported, now; zbx_uint64_t hostid; char error[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX]; DC_ITEM dc_item; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (NULL != (host = strchr(request, '\n'))) { host++; if (NULL != (p = strchr(host, '\n'))) *p = '\0'; } else { zbx_snprintf(error, sizeof(error), "host is null"); goto out; } strscpy(ip, get_ip_by_socket(sock)); if (FAIL == get_hostid_by_host(host, ip, ZBX_DEFAULT_AGENT_PORT, &hostid, error)) goto out; DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED); now = time(NULL); buffer = zbx_malloc(buffer, buffer_alloc); buffer_offset = 0; zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "select i.key_,i.delay,i.lastlogsize" " 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); result = DBselect("%s", buffer); buffer_offset = 0; 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; } } DCconfig_clean_items(&dc_item, NULL, 1); zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was successfully found in the server cache. Sending.", __function_name, row[0]); zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "%s:%s:%s\n", row[0], /* item key */ row[1], /* item delay */ row[2]); /* item lastlogsize */ } DBfree_result(result); zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, "ZBX_EOF\n"); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; alarm(0); zbx_free(buffer); out: if (FAIL == res) zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * 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_socket_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; char host[HOST_HOST_LEN_MAX], tmp[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX], error[MAX_STRING_LEN], *host_metadata = NULL; struct zbx_json json; int ret = FAIL, i; zbx_uint64_t hostid; size_t host_metadata_alloc = 1; /* for at least NUL-termination char */ unsigned short port; zbx_vector_uint64_t itemids; zbx_vector_ptr_t regexps; zbx_vector_str_t names; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(®exps); zbx_vector_str_create(&names); 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; } host_metadata = zbx_malloc(host_metadata, host_metadata_alloc); if (FAIL == zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_HOST_METADATA, &host_metadata, &host_metadata_alloc)) { *host_metadata = '\0'; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, sock->peer); 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(sock, host, ip, port, host_metadata, &hostid, error)) goto error; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); 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); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, now; zbx_config_t cfg; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == cfg.refresh_unsupported) continue; if (dc_items[i].lastclock + cfg.refresh_unsupported > now) continue; } dc_items[i].key = zbx_strdup(dc_items[i].key, dc_items[i].key_orig); substitute_key_macros(&dc_items[i].key, NULL, &dc_items[i], NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, dc_items[i].key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(dc_items[i].key, dc_items[i].key_orig)) { zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, dc_items[i].key_orig, ZBX_JSON_TYPE_STRING); } zbx_json_adduint64(&json, ZBX_PROTO_TAG_DELAY, dc_items[i].delay); /* The agent expects ALWAYS to have lastlogsize and mtime tags. */ /* Removing those would cause older agents to fail. */ zbx_json_adduint64(&json, ZBX_PROTO_TAG_LASTLOGSIZE, dc_items[i].lastlogsize); zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, dc_items[i].mtime); zbx_json_close(&json); zbx_itemkey_extract_global_regexps(dc_items[i].key, &names); zbx_free(dc_items[i].key); } zbx_config_clean(&cfg); DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_json_close(&json); DCget_expressions_by_names(®exps, (const char * const *)names.values, names.values_num); if (0 < regexps.values_num) { char buffer[32]; zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); for (i = 0; i < regexps.values_num; i++) { zbx_expression_t *regexp = regexps.values[i]; zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", regexp->name, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", regexp->expression, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->expression_type); zbx_json_addstring(&json, "expression_type", buffer, ZBX_JSON_TYPE_INT); zbx_snprintf(buffer, sizeof(buffer), "%c", regexp->exp_delimiter); zbx_json_addstring(&json, "exp_delimiter", buffer, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->case_sensitive); zbx_json_addstring(&json, "case_sensitive", buffer, ZBX_JSON_TYPE_INT); zbx_json_close(&json); } zbx_json_close(&json); } zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); zbx_alarm_on(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_socket_strerror()); else ret = SUCCEED; zbx_alarm_off(); zbx_json_free(&json); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, 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); ret = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: for (i = 0; i < names.values_num; i++) zbx_free(names.values[i]); zbx_vector_str_destroy(&names); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); zbx_free(host_metadata); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: send_list_of_active_checks * * * * Purpose: send list of active checks to the host (older version agent) * * * * Parameters: sock - open socket of server-agent connection * * request - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n * * format of the list: key:delay:last_log_size * * * ******************************************************************************/ int send_list_of_active_checks(zbx_socket_t *sock, char *request) { const char *__function_name = "send_list_of_active_checks"; char *host = NULL, *p, *buffer = NULL, error[MAX_STRING_LEN]; size_t buffer_alloc = 8 * ZBX_KIBIBYTE, buffer_offset = 0; int ret = FAIL, i; zbx_uint64_t hostid; zbx_vector_uint64_t itemids; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (NULL != (host = strchr(request, '\n'))) { host++; if (NULL != (p = strchr(host, '\n'))) *p = '\0'; } else { zbx_snprintf(error, sizeof(error), "host is null"); goto out; } /* no host metadata in older versions of agent */ if (FAIL == get_hostid_by_host(sock, host, sock->peer, ZBX_DEFAULT_AGENT_PORT, "", &hostid, error)) goto out; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); buffer = zbx_malloc(buffer, buffer_alloc); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, now; zbx_config_t cfg; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == cfg.refresh_unsupported) continue; if (dc_items[i].lastclock + cfg.refresh_unsupported > now) continue; } zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "%s:%d:" ZBX_FS_UI64 "\n", dc_items[i].key_orig, dc_items[i].delay, dc_items[i].lastlogsize); } zbx_config_clean(&cfg); DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, "ZBX_EOF\n"); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, buffer); zbx_alarm_on(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_strlcpy(error, zbx_socket_strerror(), MAX_STRING_LEN); else ret = SUCCEED; zbx_alarm_off(); zbx_free(buffer); out: if (FAIL == ret) zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * 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(®exp, ®exp_alloc, ®exp_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(®exp, ®exp_alloc, ®exp_num, pattern + 1); /*dealing with `severity' parameter*/ if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) && *key_severity == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_severity + 1); /*dealing with `logeventid' parameter*/ if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) && *key_logeventid == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_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; }