/* Update special host's item - "status" */ static void update_key_status(zbx_uint64_t hostid, int host_status, time_t now) { AGENT_RESULT agent; DB_ITEM item; DB_RESULT result; DB_ROW row; int update; zabbix_log(LOG_LEVEL_DEBUG, "In update_key_status(" ZBX_FS_UI64 ",%d)", hostid, host_status); result = DBselect("select %s where h.hostid=i.hostid and i.status=%d" " and h.proxy_hostid=0 and i.key_='%s' and h.hostid=" ZBX_FS_UI64, ZBX_SQL_ITEM_SELECT, ITEM_STATUS_ACTIVE, SERVER_STATUS_KEY, hostid); while (NULL != (row = DBfetch(result))) { DBget_item_from_db(&item, row); /* Do not process new value for status, if previous status is the same */ update = (item.lastvalue_null == 1); update = update || (item.value_type == ITEM_VALUE_TYPE_FLOAT && cmp_double(item.lastvalue_dbl, (double)host_status) == 1); update = update || (item.value_type == ITEM_VALUE_TYPE_UINT64 && item.lastvalue_uint64 != host_status); if (update) { init_result(&agent); SET_UI64_RESULT(&agent, host_status); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, now); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, now); break; } free_result(&agent); } } DBfree_result(result); }
/****************************************************************************** * * * Function: zabbix_syslog * * * * Purpose: save internal warning or error message in item zabbix[log] * * * * Parameters: va_list arguments * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: do nothing if no zabbix[log] items * * * ******************************************************************************/ void __zbx_zabbix_syslog(const char *fmt, ...) { va_list ap; char value_str[MAX_STRING_LEN]; DB_ITEM item; DB_RESULT result; DB_ROW row; AGENT_RESULT agent; time_t now; zabbix_log(LOG_LEVEL_DEBUG, "In zabbix_log()"); /* This is made to disable writing to database for watchdog */ if(CONFIG_ENABLE_LOG == 0) return; result = DBselect("select %s where h.hostid=i.hostid and h.status=%d and i.status=%d" " and h.proxy_hostid=0 and i.key_='%s' and i.value_type=%d" DB_NODE, ZBX_SQL_ITEM_SELECT, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED, SERVER_ZABBIXLOG_KEY, ITEM_VALUE_TYPE_STR, DBnode_local("h.hostid")); now = time(NULL); while((row=DBfetch(result))) { DBget_item_from_db(&item,row); va_start(ap,fmt); vsnprintf(value_str,sizeof(value_str),fmt,ap); value_str[MAX_STRING_LEN-1]=0; va_end(ap); init_result(&agent); SET_STR_RESULT(&agent, strdup(value_str)); process_new_value(&item, &agent, now); free_result(&agent); } DBfree_result(result); }
/****************************************************************************** * * * Function: zabbix_syslog * * * * Purpose: save internal warning or error message in item zabbix[log] * * * * Parameters: va_list arguments * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: do nothing if no zabbix[log] items * * * ******************************************************************************/ void __zbx_zabbix_syslog(const char *fmt, ...) { va_list ap; char value_str[MAX_STRING_LEN]; DB_ITEM item; DB_RESULT result; DB_ROW row; AGENT_RESULT agent; zabbix_log(LOG_LEVEL_DEBUG, "In zabbix_log()"); /* This is made to disable writing to database for watchdog */ if(CONFIG_ENABLE_LOG == 0) return; result = DBselect("select %s where h.hostid=i.hostid and i.key_='%s' and i.value_type=%d and " ZBX_COND_SITE, ZBX_SQL_ITEM_SELECT, SERVER_ZABBIXLOG_KEY, ITEM_VALUE_TYPE_STR, getSiteCondition ()); while((row=DBfetch(result))) { DBget_item_from_db(&item,row); va_start(ap,fmt); vsnprintf(value_str,sizeof(value_str),fmt,ap); value_str[MAX_STRING_LEN-1]=0; va_end(ap); init_result(&agent); SET_STR_RESULT(&agent, strdup(value_str)); process_new_value(0, &item,&agent, 0, NULL); free_result(&agent); update_triggers(item.itemid); DBfree_item(&item); } DBfree_result(result); }
/****************************************************************************** * * * Function: process_data * * * * Purpose: process new item value * * * * Parameters: sockfd - descriptor of agent-server socket connection * * server - server name * * key - item's key * * value - new value of server:key * * lastlogsize - if key=log[*], last size of log file * * * * Return value: SUCCEED - new value processed sucesfully * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: for trapper server process * * * ******************************************************************************/ static void process_mass_data(zbx_sock_t *sock, zbx_uint64_t proxy_hostid, AGENT_VALUE *values, int value_num, int *processed, time_t proxy_timediff) { AGENT_RESULT agent; DB_RESULT result; DB_ROW row; DB_ITEM item; char host_esc[MAX_STRING_LEN], key_esc[MAX_STRING_LEN]; static char *sql = NULL; static int sql_allocated = 65536; int sql_offset = 0, i; zabbix_log(LOG_LEVEL_DEBUG, "In process_mass_data()"); if (NULL == sql) sql = zbx_malloc(sql, sql_allocated); DCinit_nextchecks(); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 2048, "select %s where h.hostid=i.hostid and h.proxy_hostid=" ZBX_FS_UI64 " and h.status=%d and i.status in (%d,%d)", ZBX_SQL_ITEM_SELECT, proxy_hostid, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED); if (proxy_hostid == 0) { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64, " and i.type in (%d,%d)", ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE); } else { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64, " and i.type in (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)", ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_TRAPPER, ITEM_TYPE_SIMPLE, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_ZABBIX_ACTIVE, ITEM_TYPE_HTTPTEST, ITEM_TYPE_EXTERNAL, ITEM_TYPE_IPMI); } zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, " and ("); for (i = 0; i < value_num; i++) { DBescape_string(values[i].host_name, host_esc, sizeof(host_esc)); DBescape_string(values[i].key, key_esc, sizeof(key_esc)); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 512, "(h.host='%s' and i.key_='%s') or ", host_esc, key_esc); } sql_offset -= 4; zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, ")" DB_NODE, DBnode_local("h.hostid")); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { DBget_item_from_db(&item, row); if (item.type == ITEM_TYPE_ZABBIX_ACTIVE && FAIL == zbx_tcp_check_security(sock, item.trapper_hosts, 1)) continue; if (item.maintenance_status == HOST_MAINTENANCE_STATUS_ON && item.maintenance_type == MAINTENANCE_TYPE_NODATA && item.maintenance_from <= values[i].clock) continue; for (i = 0; i < value_num; i++) { if (0 == strcmp(item.host_name, values[i].host_name) && 0 == strcmp(item.key_orig, values[i].key)) { /* zabbix_log(LOG_LEVEL_DEBUG, "Processing [%s@%s: \"%s\"]", item.key, item.host_name, values[i].value);*/ if (0 == strcmp(values[i].value, "ZBX_NOTSUPPORTED")) { zabbix_log(LOG_LEVEL_WARNING, "Active parameter [%s] is not supported by agent on host [%s]", item.key_orig, item.host_name); zabbix_syslog("Active parameter [%s] is not supported by agent on host [%s]", item.key_orig, item.host_name); DCadd_nextcheck(&item, values[i].clock, proxy_timediff, "Not supported by ZABBIX agent"); if (NULL != processed) (*processed)++; } else { if (0 == strncmp(item.key, "log[", 4) || 0 == strncmp(item.key, "eventlog[", 9)) { item.lastlogsize = values[i].lastlogsize; item.timestamp = values[i].timestamp; calc_timestamp(values[i].value, &item.timestamp, item.logtimefmt); item.eventlog_severity = values[i].severity; item.eventlog_source = values[i].source; /* zabbix_log(LOG_LEVEL_DEBUG, "Value [%s] Lastlogsize [%s] Timestamp [%s]", values[i].value, item.lastlogsize, item.timestamp);*/ } init_result(&agent); if (SUCCEED == set_result_type(&agent, item.value_type, item.data_type, values[i].value)) { if (0 == CONFIG_DBSYNCER_FORKS) DBbegin(); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, values[i].clock); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, values[i].clock); break; } if (0 == CONFIG_DBSYNCER_FORKS) DBcommit(); if (NULL != processed) (*processed)++; /* only for screen Administration|Queue */ if (item.type != ITEM_TYPE_TRAPPER && item.type != ITEM_TYPE_HTTPTEST && item.value_type != ITEM_VALUE_TYPE_LOG && 0 != strcmp(item.key, SERVER_STATUS_KEY) && 0 != strcmp(item.key, SERVER_ICMPPING_KEY) && 0 != strcmp(item.key, SERVER_ICMPPINGSEC_KEY) && 0 != strcmp(item.key, SERVER_ZABBIXLOG_KEY)) DCadd_nextcheck(&item, values[i].clock, proxy_timediff, NULL); } else { if (GET_MSG_RESULT(&agent)) zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s", zbx_host_key_string_by_item(&item), agent.msg); } free_result(&agent); } } } } DBfree_result(result); DCflush_nextchecks(); }
/****************************************************************************** * * * Function: get_values * * * * Purpose: retrieve values of metrics from monitored hosts * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: always SUCCEED * * * ******************************************************************************/ static int get_values(int now, int *nextcheck) { DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; int delay; int res; DB_ITEM item; AGENT_RESULT agent; int stop = 0, items = 0; static char *unreachable_hosts = NULL; static int unreachable_hosts_alloc = 32; int unreachable_hosts_offset = 0; char istatus[16]; zabbix_log( LOG_LEVEL_DEBUG, "In get_values()"); if (0 != CONFIG_DBSYNCER_FORKS) DCinit_nextchecks(); now = time(NULL); *nextcheck = FAIL; if (NULL == unreachable_hosts) unreachable_hosts = zbx_malloc(unreachable_hosts, unreachable_hosts_alloc); *unreachable_hosts = '\0'; if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf(istatus, sizeof(istatus), "%d,%d", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED); else zbx_snprintf(istatus, sizeof(istatus), "%d", ITEM_STATUS_ACTIVE); switch (poller_type) { case ZBX_POLLER_TYPE_UNREACHABLE: result = DBselect("select h.hostid,min(i.itemid) from hosts h,items i" " where " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.nextcheck<=%d and i.status in (%d)" " and i.type in (%d,%d,%d,%d,%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from!=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and i.key_ not in ('%s','%s','%s','%s') and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " group by h.hostid", CONFIG_UNREACHABLE_POLLER_FORKS, poller_num-1, now + POLLER_DELAY, ITEM_STATUS_ACTIVE, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; case ZBX_POLLER_TYPE_IPMI: result = DBselect("select %s where i.nextcheck<=%d and i.status in (%s)" " and i.type in (%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, istatus, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, CONFIG_IPMIPOLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; default: /* ZBX_POLLER_TYPE_NORMAL */ result = DBselect("select %s where i.nextcheck<=%d and h.hostid=i.hostid and h.status=%d and i.status in (%s)" " and ((h.disable_until<=%d and h.errors_from=0 and i.type in (%d,%d,%d,%d)) or i.type in (%d,%d,%d,%d,%d))" " and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(i.itemid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, HOST_STATUS_MONITORED, istatus, now, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_SIMPLE, ITEM_TYPE_INTERNAL, ITEM_TYPE_AGGREGATE, ITEM_TYPE_EXTERNAL, ITEM_TYPE_DB_MONITOR, ITEM_TYPE_INTERNAL, CONFIG_POLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); } /* Do not stop when select is made by poller for unreachable hosts */ while((row=DBfetch(result))&&(stop==0 || poller_type == ZBX_POLLER_TYPE_UNREACHABLE)) { /* This code is just to avoid compilation warining about use of uninitialized result2 */ result2 = result; /* */ /* Poller for unreachable hosts */ if(poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { result2 = DBselect("select %s where h.hostid=i.hostid and h.proxy_hostid=0 and i.itemid=%s" DB_NODE, ZBX_SQL_ITEM_SELECT, row[1], DBnode_local("h.hostid")); row2 = DBfetch(result2); if(!row2) { DBfree_result(result2); continue; } DBget_item_from_db(&item,row2); } else { DBget_item_from_db(&item,row); /* Skip unreachable hosts but do not break the loop. */ if(uint64_in_list(unreachable_hosts,item.hostid) == SUCCEED) { zabbix_log( LOG_LEVEL_DEBUG, "Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]", item.hostid,item.key); continue; } } if (item.nextcheck > time(NULL)) { if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) DBfree_result(result2); continue; } init_result(&agent); res = get_value(&item, &agent); now = time(NULL); if (res == SUCCEED) { if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } if (item.host_errors_from != 0) { DBbegin(); DBexecute("update hosts set errors_from=0 where hostid=" ZBX_FS_UI64, item.hostid); stop = 1; DBcommit(); } if (0 == CONFIG_DBSYNCER_FORKS) DBbegin(); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, now); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, now); break; } if (0 == CONFIG_DBSYNCER_FORKS) DBcommit(); if (0 != CONFIG_DBSYNCER_FORKS) DCadd_nextcheck(&item, now, 0, NULL); if (poller_type == ZBX_POLLER_TYPE_NORMAL || poller_type == ZBX_POLLER_TYPE_IPMI) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; } else if (res == NOTSUPPORTED || res == AGENT_ERROR) { if (item.status != ITEM_STATUS_NOTSUPPORTED) { zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] is not supported by agent on host [%s] Old status [%d]", item.key, item.host_name, item.status); zabbix_syslog("Parameter [%s] is not supported by agent on host [%s]", item.key, item.host_name); } if (0 == CONFIG_DBSYNCER_FORKS) { DBbegin(); DBupdate_item_status_to_notsupported(&item, now, agent.msg); DBcommit(); } else DCadd_nextcheck(&item, now, 0, agent.msg); if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } } else if (res == NETWORK_ERROR) { DBbegin(); /* First error */ if (item.host_errors_from == 0) { zabbix_log( LOG_LEVEL_WARNING, "Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set errors_from=%d,disable_until=%d where hostid=" ZBX_FS_UI64, now, now + CONFIG_UNREACHABLE_DELAY, item.hostid); item.host_errors_from = now; delay = MIN(4*item.delay, 300); zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] will be checked after %d seconds on host [%s]", item.key, delay, item.host_name); DBexecute("update items set nextcheck=%d where itemid=" ZBX_FS_UI64, now + delay, item.itemid); } else { if (now - item.host_errors_from > CONFIG_UNREACHABLE_PERIOD) { disable_host(&item, now, agent.msg); } else { /* Still unavailable, but won't change status to UNAVAILABLE yet */ zabbix_log(LOG_LEVEL_WARNING, "Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set disable_until=%d where hostid=" ZBX_FS_UI64, now + CONFIG_UNREACHABLE_DELAY, item.hostid); } } DBcommit(); zbx_snprintf_alloc(&unreachable_hosts, &unreachable_hosts_alloc, &unreachable_hosts_offset, 32, "%s" ZBX_FS_UI64, 0 == unreachable_hosts_offset ? "" : ",", item.hostid); } else { zabbix_log(LOG_LEVEL_CRIT, "Unknown response code returned."); assert(0==1); } items++; /* Poller for unreachable hosts */ if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { /* We cannot freeit earlier because items has references to the structure */ DBfree_result(result2); } free_result(&agent); } DBfree_result(result); if (0 != CONFIG_DBSYNCER_FORKS) DCflush_nextchecks(); zabbix_log(LOG_LEVEL_DEBUG, "End get_values()"); return items; }