static int housekeeping_events(int now) { const char *__function_name = "housekeeping_events"; int event_history, deleted = 0; DB_RESULT result; DB_ROW row; zbx_uint64_t eventid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() now:%d", __function_name, now); result = DBselect("select eventid from events where clock<%d", now - *(int *)DCconfig_get_config_data(&event_history, CONFIG_EVENT_HISTORY) * SEC_PER_DAY); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(eventid, row[0]); DBexecute("delete from acknowledges where eventid=" ZBX_FS_UI64, eventid); deleted += DBexecute("delete from events where eventid=" ZBX_FS_UI64, eventid); } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted); return deleted; }
static int housekeeping_alerts(int now) { const char *__function_name = "housekeeping_alerts"; int deleted, alert_history; zabbix_log(LOG_LEVEL_DEBUG, "In %s() now:%d", __function_name, now); deleted = DBexecute("delete from alerts where clock<%d", now - *(int *)DCconfig_get_config_data(&alert_history, CONFIG_ALERT_HISTORY) * SEC_PER_DAY); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted); return deleted; }
/****************************************************************************** * * * Function: process_trap * * * * Purpose: process a single trap * * * * Parameters: addr - [IN] address of the target interface(s) * * begin - [IN] beginning of the trap message * * end - [IN] end of the trap message * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ static void process_trap(const char *addr, char *begin, char *end) { zbx_timespec_t ts; zbx_uint64_t *interfaceids = NULL; int count, i, ret = FAIL; char *trap = NULL; zbx_timespec(&ts); trap = zbx_dsprintf(trap, "%s%s", begin, end); count = DCconfig_get_snmp_interfaceids_by_addr(addr, &interfaceids); for (i = 0; i < count; i++) { if (SUCCEED == process_trap_for_interface(interfaceids[i], trap, &ts)) ret = SUCCEED; } if (FAIL == ret && 1 == *(unsigned char *)DCconfig_get_config_data(&i, CONFIG_SNMPTRAP_LOGGING)) zabbix_log(LOG_LEVEL_WARNING, "unmatched trap received from \"%s\": %s", addr, trap); zbx_free(interfaceids); zbx_free(trap); }
/****************************************************************************** * * * 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: 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; }
/****************************************************************************** * * * 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"; #define ZBX_KEY_OTHER 0 #define ZBX_KEY_LOG 1 #define ZBX_KEY_EVENTLOG 2 char host[HOST_HOST_LEN_MAX], params[MAX_STRING_LEN], 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; unsigned char item_key; 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, 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, 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, refresh_unsupported, now; 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); DCconfig_get_config_data(&refresh_unsupported, CONFIG_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 == refresh_unsupported || dc_items[i].lastclock + 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_LOGLASTSIZE, dc_items[i].lastlogsize); zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, dc_items[i].mtime); zbx_json_close(&json); if (0 == strncmp(dc_items[i].key, "log[", 4) || 0 == strncmp(dc_items[i].key, "logrt[", 6)) item_key = ZBX_KEY_LOG; else if (0 == strncmp(dc_items[i].key, "eventlog[", 9)) item_key = ZBX_KEY_EVENTLOG; else item_key = ZBX_KEY_OTHER; if (ZBX_KEY_OTHER != item_key && ZBX_COMMAND_WITH_PARAMS == parse_command(dc_items[i].key, NULL, 0, params, sizeof(params))) { /* "params" parameter */ if (0 == get_param(params, 2, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); if (ZBX_KEY_EVENTLOG == item_key) { /* "severity" parameter */ if (0 == get_param(params, 3, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); /* "source" parameter */ if (0 == get_param(params, 4, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); /* "logeventid" parameter */ if (0 == get_param(params, 5, tmp, sizeof(tmp)) && '@' == *tmp) zbx_vector_str_append_uniq(&names, tmp + 1); } } zbx_free(dc_items[i].key); } 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); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_tcp_strerror()); else ret = SUCCEED; alarm(0); zbx_json_free(&json); 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); 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_sock_t *sock, char *request) { const char *__function_name = "send_list_of_active_checks"; char *host = NULL, *p, *buffer = NULL, error[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX]; 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; } strscpy(ip, get_ip_by_socket(sock)); /* no host metadata in older versions of agent */ if (FAIL == get_hostid_by_host(host, ip, 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, refresh_unsupported, now; 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); DCconfig_get_config_data(&refresh_unsupported, CONFIG_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 == refresh_unsupported || dc_items[i].lastclock + 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); } 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); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_strlcpy(error, zbx_tcp_strerror(), MAX_STRING_LEN); else ret = SUCCEED; alarm(0); zbx_free(buffer); out: if (FAIL == ret) { 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(ret)); return ret; }