/****************************************************************************** * * * Function: main_timer_loop * * * * Purpose: periodically updates time-related triggers * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: does update once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_timer_loop() { int now, cur; /* int itemid,functionid; char *function; char *parameter;*/ DB_ITEM item; DB_RESULT result; DB_ROW row; for(;;) { zbx_setproctitle("Timer: updating nodata() functions"); DBconnect(ZBX_DB_CONNECT_NORMAL); now=time(NULL); /* #ifdef HAVE_POSTGRESQL zbx_snprintf(sql,sizeof(sql),"select distinct f.itemid,f.functionid,f.parameter from functions f, items i,hosts h where h.hostid=i.hostid and h.status=%d and i.itemid=f.itemid and f.function in ('nodata','date','dayofweek','time','now') and i.lastclock+f.parameter::text::integer<=%d and i.status=%d", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE); #else zbx_snprintf(sql,sizeof(sql),"select distinct f.itemid,f.functionid,f.parameter,f.function from functions f, items i,hosts h where h.hostid=i.hostid and h.status=%d and i.itemid=f.itemid and f.function in ('nodata','date','dayofweek','time','now') and i.lastclock+f.parameter<=%d and i.status=%d", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE); #endif */ result = DBselect("select %s, functions f where h.hostid=i.hostid and h.status=%d and i.status=%d and f.function in ('nodata','date','dayofweek','time','now','count') and i.itemid=f.itemid and " ZBX_COND_SITE, ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, getSiteCondition ()); cur = 1; while((row=DBfetch(result))) { #ifdef HAVE_MYSQL zbx_setproctitle("Timer: processing %d item of %d", cur++, result->row_count); #endif DBget_item_from_db(&item,row); DBbegin(); update_functions(&item); update_triggers(item.itemid); DBcommit(); DBfree_item(&item); } DBfree_result(result); DBclose(); zbx_setproctitle("Timer: sleeping for 10 sec"); sleep(10); } }
/* 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: 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; }
static int calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp, char *error, int max_error_len) { const char *__function_name = "calcitem_evaluate_expression"; function_t *f = NULL; char *sql = NULL, *host_esc, *key_esc, *buf, replace[16]; int sql_alloc = 1024, sql_offset = 0, i, ret = SUCCEED; time_t now; DB_RESULT db_result; DB_ROW db_row; DB_ITEM item; zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:'%s'", __function_name, exp->exp); if (0 == exp->functions_num) return ret; for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; buf = get_param_dyn(f->params, 1); /* for first parameter result is not NULL */ if (SUCCEED != parse_host_key(buf, &f->host, &f->key)) { zbx_snprintf(error, max_error_len, "Invalid first parameter in function [%s(%s)]", f->func, f->params); ret = NOTSUPPORTED; } zbx_free(buf); if (SUCCEED != ret) break; if (NULL == f->host) f->host = strdup(dc_item->host.host); remove_param(f->params, 1); zabbix_log(LOG_LEVEL_DEBUG, "%s() function:'%s:%s.%s(%s)'", __function_name, f->host, f->key, f->func, f->params); } if (SUCCEED != ret) return ret; now = time(NULL); sql = zbx_malloc(sql, sql_alloc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "select %s" " where h.hostid=i.hostid" " and h.status=%d" " and i.status=%d" " and (", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE); for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; if (i != 0) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, " or "); host_esc = DBdyn_escape_string(f->host); key_esc = DBdyn_escape_string(f->key); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 32 + strlen(host_esc) + strlen(key_esc), "(h.host='%s' and i.key_='%s')", host_esc, key_esc); zbx_free(key_esc); zbx_free(host_esc); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 130, ")" DB_NODE, DBnode_local("h.hostid")); db_result = DBselect("%s", sql); zbx_free(sql); while (NULL != (db_row = DBfetch(db_result))) { DBget_item_from_db(&item, db_row); for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; if (0 != strcmp(f->key, item.key_orig)) continue; if (0 != strcmp(f->host, item.host_name)) continue; f->found = 1; f->value = zbx_malloc(f->value, MAX_BUFFER_LEN); if (SUCCEED != evaluate_function(f->value, &item, f->func, f->params, now)) { zbx_snprintf(error, max_error_len, "Cannot evaluate function [%s(%s)]", f->func, f->params); ret = NOTSUPPORTED; break; } else f->value = zbx_realloc(f->value, strlen(f->value) + 1); } if (SUCCEED != ret) break; } DBfree_result(db_result); if (SUCCEED != ret) return ret; for (i = 0; i < exp->functions_num; i ++) { f = &exp->functions[i]; if (0 == f->found) { zbx_snprintf(error, max_error_len, "Cannot evaluate function [%s(%s)]" ": item [%s:%s] not found", f->func, f->params, f->host, f->key); ret = NOTSUPPORTED; break; } zbx_snprintf(replace, sizeof(replace), "{%d}", f->functionid); buf = string_replace(exp->exp, replace, f->value); zbx_free(exp->exp); exp->exp = buf; } return ret; }
/****************************************************************************** * * * 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; }
/****************************************************************************** * * * 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; }