/****************************************************************************** * * * Function: main_dbconfig_loop * * * * Purpose: periodically synchronises database data with memory cache * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_dbconfig_loop(void) { double sec = 0.0; zbx_setproctitle("%s [waiting %d sec for processes]", get_process_type_string(process_type), CONFIG_CONFSYNCER_FREQUENCY); /* the initial configuration sync is done by server before worker processes are forked */ zbx_sleep_loop(CONFIG_CONFSYNCER_FREQUENCY); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, syncing configuration]", get_process_type_string(process_type), sec); sec = zbx_time(); DCsync_configuration(); sec = zbx_time() - sec; zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, CONFIG_CONFSYNCER_FREQUENCY); zbx_sleep_loop(CONFIG_CONFSYNCER_FREQUENCY); } }
/****************************************************************************** * * * Function: main_escalator_loop * * * * Purpose: periodically check table escalations and generate alerts * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_escalator_loop() { int now; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_escalator_loop()"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [processing escalations]", get_process_type_string(process_type)); now = time(NULL); sec = zbx_time(); process_escalations(now); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while processing escalations", get_process_type_string(process_type), process_num, sec); zbx_sleep_loop(CONFIG_ESCALATOR_FREQUENCY); } }
/****************************************************************************** * * * Function: main_snmptrapper_loop * * * * Purpose: SNMP trap reader's entry point * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ void main_snmptrapper_loop() { const char *__function_name = "main_snmptrapper_loop"; zabbix_log(LOG_LEVEL_DEBUG, "In %s() trapfile:'%s'", __function_name, CONFIG_SNMPTRAP_FILE); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); DBget_lastsize(); for (;;) { zbx_setproctitle("%s [processing data]", get_process_type_string(process_type)); while (SUCCEED == get_latest_data()) read_traps(); zbx_sleep_loop(1); } if (-1 != trap_fd) close(trap_fd); }
void main_housekeeper_loop(void) { int records, start, sleeptime; double sec; for (;;) { start = time(NULL); zabbix_log(LOG_LEVEL_WARNING, "executing housekeeper"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); zbx_setproctitle("%s [removing old history]", get_process_type_string(process_type)); sec = zbx_time(); records = housekeeping_history(start); sec = zbx_time() - sec; DBclose(); sleeptime = CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR - (time(NULL) - start); zabbix_log(LOG_LEVEL_WARNING, "%s [deleted %d records in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), records, sec, sleeptime); zbx_setproctitle("%s [deleted %d records in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), records, sec, sleeptime); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_pinger_loop * * * * Purpose: periodically perform ICMP pings * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_pinger_loop(void) { int nextcheck, sleeptime; double sec; static icmpitem_t *items = NULL; static int items_alloc = 4; int items_count = 0, itc; if (NULL == items) items = zbx_malloc(items, sizeof(icmpitem_t) * items_alloc); for (;;) { zbx_setproctitle("%s #%d [getting values]", get_process_type_string(process_type), process_num); sec = zbx_time(); get_pinger_hosts(&items, &items_alloc, &items_count); process_pinger_hosts(items, items_count); sec = zbx_time() - sec; itc = items_count; free_hosts(&items, &items_count); nextcheck = DCconfig_get_poller_nextcheck(ZBX_POLLER_TYPE_PINGER); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), process_num, itc, sec, sleeptime); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_nodewatcher_loop * * * * Purpose: periodically calculates checksum of config data * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_nodewatcher_loop() { int start, end; int lastrun = 0; zabbix_log(LOG_LEVEL_DEBUG, "In main_nodewatcher_loop()"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [exchanging data]", get_process_type_string(process_type)); start = time(NULL); zabbix_log(LOG_LEVEL_DEBUG, "Starting sync with nodes"); if (lastrun + 120 < start) { process_nodes(); lastrun = start; } /* send new history data to master node */ main_historysender(); end = time(NULL); zbx_sleep_loop(10 - (end - start)); } }
void main_poller_loop(unsigned char poller_type) { int nextcheck, sleeptime, processed; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_poller_loop() process_type:'%s' process_num:%d", get_process_type_string(process_type), process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [getting values]", get_process_type_string(process_type)); sec = zbx_time(); processed = get_values(poller_type); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while updating %d values", get_process_type_string(process_type), process_num, sec, processed); nextcheck = DCconfig_get_poller_nextcheck(poller_type); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_watchdog_loop * * * * Purpose: check database availability every DB_PING_FREQUENCY seconds and * * alert admins if it is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ void main_watchdog_loop() { int now, nextsync = 0; zabbix_log(LOG_LEVEL_DEBUG, "In main_watchdog_loop()"); /* disable writing to database in zabbix_syslog() */ CONFIG_ENABLE_LOG = 0; zbx_vector_ptr_create(&recipients); for (;;) { zbx_setproctitle("%s [pinging database]", get_process_type_string(process_type)); if (ZBX_DB_OK != DBconnect(ZBX_DB_CONNECT_ONCE)) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); } else if (nextsync <= (now = (int)time(NULL))) { zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type)); sync_config(); nextsync = now + CONFIG_CONFSYNCER_FREQUENCY; } DBclose(); zbx_sleep_loop(DB_PING_FREQUENCY); } }
/****************************************************************************** * * * Function: main_discoverer_loop * * * * Purpose: periodically try to find new hosts and services * * * * Author: Alexei Vladishev * * * * Comments: executes once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_discoverer_loop() { int now, nextcheck, sleeptime; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_discoverer_loop() process_num:%d", process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [performing discovery]", get_process_type_string(process_type)); now = time(NULL); sec = zbx_time(); process_discovery(now); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while processing rules", get_process_type_string(process_type), process_num, sec); nextcheck = get_minnextcheck(now); sleeptime = calculate_sleeptime(nextcheck, DISCOVERER_DELAY); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_httppoller_loop * * * * Purpose: main loop of processing of httptests * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_httppoller_loop() { int now, nextcheck, sleeptime; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_httppoller_loop() process_num:%d", process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [getting values]", get_process_type_string(process_type)); now = time(NULL); sec = zbx_time(); process_httptests(process_num, now); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while updating HTTP tests", get_process_type_string(process_type), process_num, sec); nextcheck = get_minnextcheck(now); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_datasender_loop * * * * Purpose: periodically sends history and events to the server * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ ZBX_THREAD_ENTRY(datasender_thread, args) { int records = 0, r; double sec = 0.0; struct zbx_json j; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); zbx_json_init(&j, 16 * ZBX_KIBIBYTE); for (;;) { zbx_setproctitle("%s [sent %d values in " ZBX_FS_DBL " sec, sending data]", get_process_type_string(process_type), records, sec); sec = zbx_time(); host_availability_sender(&j); records = 0; retry_history: history_sender(&j, &r, ZBX_PROTO_VALUE_HISTORY_DATA, proxy_get_hist_data, proxy_set_hist_lastid); records += r; if (ZBX_MAX_HRECORDS == r) goto retry_history; retry_dhistory: history_sender(&j, &r, ZBX_PROTO_VALUE_DISCOVERY_DATA, proxy_get_dhis_data, proxy_set_dhis_lastid); records += r; if (ZBX_MAX_HRECORDS == r) goto retry_dhistory; retry_autoreg_host: history_sender(&j, &r, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA, proxy_get_areg_data, proxy_set_areg_lastid); records += r; if (ZBX_MAX_HRECORDS == r) goto retry_autoreg_host; sec = zbx_time() - sec; zbx_setproctitle("%s [sent %d values in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), records, sec, CONFIG_PROXYDATA_FREQUENCY); zbx_sleep_loop(CONFIG_PROXYDATA_FREQUENCY); } }
/****************************************************************************** * * * Function: main_heart_loop * * * * Purpose: periodically send heartbeat message to the server * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void main_heart_loop(void) { int start, sleeptime = 0, res; double sec, total_sec = 0.0, old_total_sec = 0.0; time_t last_stat_time; #define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */ /* once in STAT_INTERVAL seconds */ last_stat_time = time(NULL); zbx_setproctitle("%s [sending heartbeat message]", get_process_type_string(process_type)); for (;;) { if (0 != sleeptime) { zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, " "sending heartbeat message]", get_process_type_string(process_type), SUCCEED == res ? "success" : "failed", old_total_sec); } start = time(NULL); sec = zbx_time(); res = send_heartbeat(); total_sec += zbx_time() - sec; sleeptime = CONFIG_HEARTBEAT_FREQUENCY - (time(NULL) - start); if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time) { if (0 == sleeptime) { zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, " "sending heartbeat message]", get_process_type_string(process_type), SUCCEED == res ? "success" : "failed", total_sec); } else { zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, " "idle %d sec]", get_process_type_string(process_type), SUCCEED == res ? "success" : "failed", total_sec, sleeptime); old_total_sec = total_sec; } total_sec = 0.0; last_stat_time = time(NULL); } zbx_sleep_loop(sleeptime); } #undef STAT_INTERVAL }
/****************************************************************************** * * * Function: main_discoverer_loop * * * * Purpose: periodically try to find new hosts and services * * * * Author: Alexei Vladishev * * * * Comments: executes once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_discoverer_loop(void) { int now, nextcheck, sleeptime = -1, rule_count = 0, old_rule_count = 0; double sec, total_sec = 0.0, old_total_sec = 0.0; time_t last_stat_time; #define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */ /* once in STAT_INTERVAL seconds */ zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num); last_stat_time = time(NULL); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { if (0 != sleeptime) { zbx_setproctitle("%s #%d [processed %d rules in " ZBX_FS_DBL " sec, performing discovery]", get_process_type_string(process_type), process_num, old_rule_count, old_total_sec); } now = time(NULL); sec = zbx_time(); rule_count += process_discovery(now); total_sec += zbx_time() - sec; nextcheck = get_minnextcheck(now); sleeptime = calculate_sleeptime(nextcheck, DISCOVERER_DELAY); if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time) { if (0 == sleeptime) { zbx_setproctitle("%s #%d [processed %d rules in " ZBX_FS_DBL " sec, performing " "discovery]", get_process_type_string(process_type), process_num, rule_count, total_sec); } else { zbx_setproctitle("%s #%d [processed %d rules in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), process_num, rule_count, total_sec, sleeptime); old_rule_count = rule_count; old_total_sec = total_sec; } rule_count = 0; total_sec = 0.0; last_stat_time = time(NULL); } zbx_sleep_loop(sleeptime); } #undef STAT_INTERVAL }
/****************************************************************************** * * * Function: main_watchdog_loop * * * * Purpose: check database availability every DB_PING_FREQUENCY seconds and * * alert admins if it is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ ZBX_THREAD_ENTRY(watchdog_thread, args) { int now, nextsync = 0, action; double sec; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); zbx_vector_ptr_create(&recipients); for (;;) { zbx_setproctitle("%s [pinging database]", get_process_type_string(process_type)); sec = zbx_time(); action = 0; if (ZBX_DB_OK != DBconnect(ZBX_DB_CONNECT_ONCE)) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); action = 1; } else if (nextsync <= (now = (int)time(NULL))) { zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type)); sync_config(); nextsync = now + CONFIG_CONFSYNCER_FREQUENCY; action = 2; } DBclose(); sec = zbx_time() - sec; if (1 == action) { zbx_setproctitle("%s [database is down, checking took " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, (int)DB_PING_FREQUENCY); } else if (2 == action) { zbx_setproctitle("%s [synced alerts config in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, (int)DB_PING_FREQUENCY); } zbx_sleep_loop(DB_PING_FREQUENCY); } }
/****************************************************************************** * * * Function: main_dbconfig_loop * * * * Purpose: periodically synchronises database data with memory cache * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ ZBX_THREAD_ENTRY(dbconfig_thread, args) { double sec = 0.0; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type), server_num, get_process_type_string(process_type), process_num); zbx_setproctitle("%s [waiting %d sec for processes]", get_process_type_string(process_type), CONFIG_CONFSYNCER_FREQUENCY); zbx_set_sigusr_handler(zbx_dbconfig_sigusr_handler); /* the initial configuration sync is done by server before worker processes are forked */ zbx_sleep_loop(CONFIG_CONFSYNCER_FREQUENCY); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_handle_log(); zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, syncing configuration]", get_process_type_string(process_type), sec); sec = zbx_time(); DCsync_configuration(); DCupdate_hosts_availability(); sec = zbx_time() - sec; zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, CONFIG_CONFSYNCER_FREQUENCY); zbx_sleep_loop(CONFIG_CONFSYNCER_FREQUENCY); } }
ZBX_THREAD_ENTRY(taskmanager_thread, args) { static int cleanup_time = 0; double sec1, sec2; int tasks_num, sleeptime, nextcheck; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type), server_num, get_process_type_string(process_type), process_num); #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) zbx_tls_init_child(); #endif zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); sec1 = zbx_time(); sleeptime = ZBX_TM_PROCESS_PERIOD - (int)sec1 % ZBX_TM_PROCESS_PERIOD; zbx_setproctitle("%s [started, idle %d sec]", get_process_type_string(process_type), sleeptime); for (;;) { zbx_sleep_loop(sleeptime); sec1 = zbx_time(); zbx_update_env(sec1); zbx_setproctitle("%s [processing tasks]", get_process_type_string(process_type)); tasks_num = tm_process_tasks((int)sec1); if (ZBX_TM_CLEANUP_PERIOD <= sec1 - cleanup_time) { tm_remove_old_tasks((int)sec1); cleanup_time = sec1; } sec2 = zbx_time(); nextcheck = (int)sec1 - (int)sec1 % ZBX_TM_PROCESS_PERIOD + ZBX_TM_PROCESS_PERIOD; if (0 > (sleeptime = nextcheck - (int)sec2)) sleeptime = 0; zbx_setproctitle("%s [processed %d task(s) in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), tasks_num, sec2 - sec1, sleeptime); } }
void main_housekeeper_loop() { int d, now; set_child_signal_handler(); for (;;) { zabbix_log(LOG_LEVEL_WARNING, "Executing housekeeper"); now = time(NULL); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); /* Transaction is not required here. It causes timeouts under MySQL. */ /* DBbegin();*/ zbx_setproctitle("%s [removing old history]", get_process_type_string(process_type)); d = housekeeping_history_and_trends(now); zabbix_log(LOG_LEVEL_WARNING, "Deleted %d records from history and trends", d); zbx_setproctitle("%s [removing old history]", get_process_type_string(process_type)); housekeeping_process_log(now); zbx_setproctitle("%s [removing old events]", get_process_type_string(process_type)); housekeeping_events(now); zbx_setproctitle("%s [removing old alerts]", get_process_type_string(process_type)); housekeeping_alerts(now); zbx_setproctitle("%s [removing old sessions]", get_process_type_string(process_type)); housekeeping_sessions(now); /* Transaction is not required here. It causes timeouts under MySQL. */ /* DBcommit();*/ /* zbx_setproctitle("housekeeper [vacuuming database]");*/ /* DBvacuum();*/ DBclose(); zbx_sleep_loop(SEC_PER_HOUR * CONFIG_HOUSEKEEPING_FREQUENCY); } }
void main_housekeeper_loop(void) { int now, d_history_and_trends, d_cleanup, d_events, d_sessions, d_services, d_audit; double sec; for (;;) { zabbix_log(LOG_LEVEL_WARNING, "executing housekeeper"); now = time(NULL); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); DCconfig_get_config_hk(&hk_config); zbx_setproctitle("%s [removing old history and trends]", get_process_type_string(process_type)); sec = zbx_time(); d_history_and_trends = housekeeping_history_and_trends(now); zbx_setproctitle("%s [removing deleted items data]", get_process_type_string(process_type)); d_cleanup = housekeeping_cleanup(); zbx_setproctitle("%s [removing old events]", get_process_type_string(process_type)); d_events = housekeeping_events(now); zbx_setproctitle("%s [removing old sessions]", get_process_type_string(process_type)); d_sessions = housekeeping_sessions(now); zbx_setproctitle("%s [removing old service alarms]", get_process_type_string(process_type)); d_services = housekeeping_services(now); zbx_setproctitle("%s [removing old audit log items]", get_process_type_string(process_type)); d_audit = housekeeping_audit(now); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_WARNING, "%s [deleted %d hist/trends, %d items, %d events, %d sessions, %d alarms," " %d audit items in " ZBX_FS_DBL " sec, idle %d hour(s)]", get_process_type_string(process_type), d_history_and_trends, d_cleanup, d_events, d_sessions, d_services, d_audit, sec, CONFIG_HOUSEKEEPING_FREQUENCY); DBclose(); zbx_setproctitle("%s [deleted %d hist/trends, %d items, %d events, %d sessions, %d alarms, %d audit " "items in " ZBX_FS_DBL " sec, idle %d hour(s)]", get_process_type_string(process_type), d_history_and_trends, d_cleanup, d_events, d_sessions, d_services, d_audit, sec, CONFIG_HOUSEKEEPING_FREQUENCY); zbx_sleep_loop(CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR); } }
void main_selfmon_loop() { const char *__function_name = "main_selfmon_loop"; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); set_child_signal_handler(); for (;;) { zbx_setproctitle("%s [processing data]", get_process_type_string(process_type)); collect_selfmon_stats(); zbx_sleep_loop(1); } }
/****************************************************************************** * * * Function: main_proxyconfig_loop * * * * Purpose: periodically request config data * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_proxyconfig_loop() { zabbix_log(LOG_LEVEL_DEBUG, "In main_proxyconfig_loop()"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [loading configuration]", get_process_type_string(process_type)); process_configuration_sync(); zbx_sleep_loop(CONFIG_PROXYCONFIG_FREQUENCY); } }
/****************************************************************************** * * * Function: main_snmptrapper_loop * * * * Purpose: SNMP trap reader's entry point * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ ZBX_THREAD_ENTRY(snmptrapper_thread, args) { const char *__function_name = "main_snmptrapper_loop"; double sec; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type), server_num, get_process_type_string(process_type), process_num); zabbix_log(LOG_LEVEL_DEBUG, "In %s() trapfile:'%s'", __function_name, CONFIG_SNMPTRAP_FILE); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); DBget_lastsize(); buffer = zbx_malloc(buffer, MAX_BUFFER_LEN); *buffer = '\0'; for (;;) { zbx_handle_log(); zbx_setproctitle("%s [processing data]", get_process_type_string(process_type)); sec = zbx_time(); while (SUCCEED == get_latest_data()) read_traps(); sec = zbx_time() - sec; zbx_setproctitle("%s [processed data in " ZBX_FS_DBL " sec, idle 1 sec]", get_process_type_string(process_type), sec); zbx_sleep_loop(1); } zbx_free(buffer); if (-1 != trap_fd) close(trap_fd); }
/****************************************************************************** * * * Function: main_heart_loop * * * * Purpose: periodically send heartbeat message to the server * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void main_heart_loop() { int start, sleeptime; zabbix_log(LOG_LEVEL_DEBUG, "In main_heart_loop()"); for (;;) { start = time(NULL); zbx_setproctitle("%s [sending heartbeat message]", get_process_type_string(process_type)); send_heartbeat(); sleeptime = CONFIG_HEARTBEAT_FREQUENCY - (time(NULL) - start); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_pinger_loop * * * * Purpose: periodically perform ICMP pings * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ ZBX_THREAD_ENTRY(pinger_thread, args) { int nextcheck, sleeptime, items_count = 0, itc; double sec; static icmpitem_t *items = NULL; static int items_alloc = 4; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); if (NULL == items) items = zbx_malloc(items, sizeof(icmpitem_t) * items_alloc); for (;;) { zbx_setproctitle("%s #%d [getting values]", get_process_type_string(process_type), process_num); sec = zbx_time(); get_pinger_hosts(&items, &items_alloc, &items_count); process_pinger_hosts(items, items_count); sec = zbx_time() - sec; itc = items_count; free_hosts(&items, &items_count); nextcheck = DCconfig_get_poller_nextcheck(ZBX_POLLER_TYPE_PINGER); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), process_num, itc, sec, sleeptime); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_pinger_loop * * * * Purpose: periodically perform ICMP pings * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_pinger_loop() { int nextcheck, sleeptime; double sec; static icmpitem_t *items = NULL; static int items_alloc = 4; int items_count = 0; zabbix_log(LOG_LEVEL_DEBUG, "In main_pinger_loop() process_num:%d", process_num); if (NULL == items) items = zbx_malloc(items, sizeof(icmpitem_t) * items_alloc); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [getting values]", get_process_type_string(process_type)); sec = zbx_time(); get_pinger_hosts(&items, &items_alloc, &items_count); process_pinger_hosts(items, items_count); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while processing %d items", get_process_type_string(process_type), process_num, sec, items_count); free_hosts(&items, &items_count); nextcheck = DCconfig_get_poller_nextcheck(ZBX_POLLER_TYPE_PINGER); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_sleep_loop(sleeptime); } }
void main_housekeeper_loop() { int now, d_history_and_trends, d_cleanup, d_events, d_alerts, d_sessions; for (;;) { zabbix_log(LOG_LEVEL_WARNING, "executing housekeeper"); now = time(NULL); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); zbx_setproctitle("%s [removing old history and trends]", get_process_type_string(process_type)); d_history_and_trends = housekeeping_history_and_trends(now); zbx_setproctitle("%s [removing deleted items data]", get_process_type_string(process_type)); d_cleanup = housekeeping_cleanup(); zbx_setproctitle("%s [removing old events]", get_process_type_string(process_type)); d_events = housekeeping_events(now); zbx_setproctitle("%s [removing old alerts]", get_process_type_string(process_type)); d_alerts = housekeeping_alerts(now); zbx_setproctitle("%s [removing old sessions]", get_process_type_string(process_type)); d_sessions = housekeeping_sessions(now); zabbix_log(LOG_LEVEL_WARNING, "housekeeper deleted: %d records from history and trends," " %d records of deleted items, %d events, %d alerts, %d sessions", d_history_and_trends, d_cleanup, d_events, d_alerts, d_sessions); DBclose(); zbx_sleep_loop(CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR); } }
/****************************************************************************** * * * Function: main_alerter_loop * * * * Purpose: periodically check table alerts and send notifications if needed * * * * Author: Alexei Vladishev * * * ******************************************************************************/ ZBX_THREAD_ENTRY(alerter_thread, args) { char error[MAX_STRING_LEN], *error_esc; int res, alerts_success, alerts_fail; double sec; DB_RESULT result; DB_ROW row; DB_ALERT alert; DB_MEDIATYPE mediatype; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [sending alerts]", get_process_type_string(process_type)); sec = zbx_time(); alerts_success = alerts_fail = 0; result = DBselect( "select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid," "mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path," "mt.gsm_modem,mt.username,mt.passwd,mt.smtp_port,mt.smtp_security," "mt.smtp_verify_peer,mt.smtp_verify_host,mt.smtp_authentication,a.retries" " from alerts a,media_type mt" " where a.mediatypeid=mt.mediatypeid" " and a.status=%d" " and a.alerttype=%d" " order by a.alertid", ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(alert.alertid, row[0]); ZBX_STR2UINT64(alert.mediatypeid, row[1]); alert.sendto = row[2]; alert.subject = row[3]; alert.message = row[4]; alert.status = atoi(row[5]); ZBX_STR2UINT64(mediatype.mediatypeid, row[6]); mediatype.type = atoi(row[7]); mediatype.description = row[8]; mediatype.smtp_server = row[9]; mediatype.smtp_helo = row[10]; mediatype.smtp_email = row[11]; mediatype.exec_path = row[12]; mediatype.gsm_modem = row[13]; mediatype.username = row[14]; mediatype.passwd = row[15]; mediatype.smtp_port = (unsigned short)atoi(row[16]); ZBX_STR2UCHAR(mediatype.smtp_security, row[17]); ZBX_STR2UCHAR(mediatype.smtp_verify_peer, row[18]); ZBX_STR2UCHAR(mediatype.smtp_verify_host, row[19]); ZBX_STR2UCHAR(mediatype.smtp_authentication, row[20]); alert.retries = atoi(row[21]); *error = '\0'; res = execute_action(&alert, &mediatype, error, sizeof(error)); if (SUCCEED == res) { zabbix_log(LOG_LEVEL_DEBUG, "alert ID [" ZBX_FS_UI64 "] was sent successfully", alert.alertid); DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64, ALERT_STATUS_SENT, alert.alertid); alerts_success++; } else { zabbix_log(LOG_LEVEL_DEBUG, "error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid); error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN); alert.retries++; if (ALERT_MAX_RETRIES > alert.retries) { DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64, alert.retries, error_esc, alert.alertid); } else { DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64, ALERT_STATUS_FAILED, alert.retries, error_esc, alert.alertid); } zbx_free(error_esc); alerts_fail++; } } DBfree_result(result); sec = zbx_time() - sec; zbx_setproctitle("%s [sent alerts: %d success, %d fail in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), alerts_success, alerts_fail, sec, CONFIG_SENDER_FREQUENCY); zbx_sleep_loop(CONFIG_SENDER_FREQUENCY); } }
/****************************************************************************** * * * 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(void) { int now, nextcheck, sleeptime = -1, triggers_count = 0, events_count = 0, hm_count = 0, old_triggers_count = 0, old_events_count = 0, old_hm_count = 0, tr_count, ev_count; double sec = 0.0, sec_maint = 0.0, total_sec = 0.0, total_sec_maint = 0.0, old_total_sec = 0.0, old_total_sec_maint = 0.0; time_t last_stat_time; #define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */ /* once in STAT_INTERVAL seconds */ zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num); last_stat_time = time(NULL); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { now = time(NULL); nextcheck = now + TIMER_DELAY - (now % TIMER_DELAY); sleeptime = nextcheck - now; if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time) { if (0 == sleeptime) { if (1 != process_num) { zbx_setproctitle("%s #%d [processed %d triggers, %d events in " ZBX_FS_DBL " sec, processing time functions]", get_process_type_string(process_type), process_num, triggers_count, events_count, total_sec); } else { zbx_setproctitle("%s #1 [processed %d triggers, %d events in " ZBX_FS_DBL " sec, %d maint.periods in " ZBX_FS_DBL " sec, processing time " "functions]", get_process_type_string(process_type), triggers_count, events_count, total_sec, hm_count, total_sec_maint); } } else { if (1 != process_num) { zbx_setproctitle("%s #%d [processed %d triggers, %d events in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), process_num, triggers_count, events_count, total_sec, sleeptime); } else { zbx_setproctitle("%s #1 [processed %d triggers, %d events in " ZBX_FS_DBL " sec, %d maint.periods in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), triggers_count, events_count, total_sec, hm_count, total_sec_maint, sleeptime); old_hm_count = hm_count; old_total_sec_maint = total_sec_maint; } old_triggers_count = triggers_count; old_events_count = events_count; old_total_sec = total_sec; } triggers_count = 0; events_count = 0; hm_count = 0; total_sec = 0.0; total_sec_maint = 0.0; last_stat_time = time(NULL); } zbx_sleep_loop(sleeptime); if (0 != sleeptime) { if (1 != process_num) { zbx_setproctitle("%s #%d [processed %d triggers, %d events in " ZBX_FS_DBL " sec, processing time functions]", get_process_type_string(process_type), process_num, old_triggers_count, old_events_count, old_total_sec); } else { zbx_setproctitle("%s #1 [processed %d triggers, %d events in " ZBX_FS_DBL " sec, %d maint.periods in " ZBX_FS_DBL " sec, processing time " "functions]", get_process_type_string(process_type), old_triggers_count, old_events_count, old_total_sec, old_hm_count, old_total_sec_maint); } } sec = zbx_time(); tr_count = 0; ev_count = 0; process_time_functions(&tr_count, &ev_count); triggers_count += tr_count; events_count += ev_count; total_sec += zbx_time() - sec; /* only the "timer #1" process evaluates the maintenance periods */ if (1 != process_num) continue; /* we process maintenance at every 00 sec */ /* process time functions can take long time */ if (0 == nextcheck % SEC_PER_MIN || nextcheck + SEC_PER_MIN - (nextcheck % SEC_PER_MIN) <= time(NULL)) { zbx_setproctitle("%s #1 [processed %d triggers, %d events in " ZBX_FS_DBL " sec, %d maint.periods in " ZBX_FS_DBL " sec, processing maintenance periods]", get_process_type_string(process_type), triggers_count, events_count, total_sec, old_hm_count, old_total_sec_maint); sec_maint = zbx_time(); hm_count += process_maintenance(); total_sec_maint += zbx_time() - sec_maint; } } #undef STAT_INTERVAL }
/****************************************************************************** * * * Function: main_alerter_loop * * * * Purpose: periodically check table alerts and send notifications if needed * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_alerter_loop() { char error[MAX_STRING_LEN], *error_esc; int res, now; DB_RESULT result; DB_ROW row; DB_ALERT alert; DB_MEDIATYPE mediatype; set_child_signal_handler(); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [sending alerts]", get_process_type_string(process_type)); now = time(NULL); result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid" ",mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path" ",mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt" " where a.status=%d and a.mediatypeid=mt.mediatypeid and a.alerttype=%d" DB_NODE " order by a.clock", ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE, DBnode_local("mt.mediatypeid")); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(alert.alertid, row[0]); alert.mediatypeid = atoi(row[1]); alert.sendto = row[2]; alert.subject = row[3]; alert.message = row[4]; alert.status = atoi(row[5]); ZBX_STR2UINT64(mediatype.mediatypeid, row[6]); mediatype.type = atoi(row[7]); mediatype.description = row[8]; mediatype.smtp_server = row[9]; mediatype.smtp_helo = row[10]; mediatype.smtp_email = row[11]; mediatype.exec_path = row[12]; mediatype.gsm_modem = row[13]; mediatype.username = row[14]; mediatype.passwd = row[15]; alert.retries = atoi(row[16]); *error = '\0'; res = execute_action(&alert, &mediatype, error, sizeof(error)); if (res == SUCCEED) { zabbix_log(LOG_LEVEL_DEBUG, "Alert ID [" ZBX_FS_UI64 "] was sent successfully", alert.alertid); DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64, ALERT_STATUS_SENT, alert.alertid); } else { zabbix_log(LOG_LEVEL_DEBUG, "Error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid); zabbix_syslog("Error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid); error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN); alert.retries++; if (alert.retries < ALERT_MAX_RETRIES) { DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64, alert.retries, error_esc, alert.alertid); } else { DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64, ALERT_STATUS_FAILED, alert.retries, error_esc, alert.alertid); } zbx_free(error_esc); } } DBfree_result(result); zbx_sleep_loop(CONFIG_SENDER_FREQUENCY); } }
ZBX_THREAD_ENTRY(housekeeper_thread, args) { int records, start, sleeptime; double sec, time_slept; char sleeptext[25]; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); if (0 == CONFIG_HOUSEKEEPING_FREQUENCY) { zbx_setproctitle("%s [waiting for user command]", get_process_type_string(process_type)); zbx_snprintf(sleeptext, sizeof(sleeptext), "waiting for user command"); } else { sleeptime = HOUSEKEEPER_STARTUP_DELAY * SEC_PER_MIN; zbx_setproctitle("%s [startup idle for %d minutes]", get_process_type_string(process_type), HOUSEKEEPER_STARTUP_DELAY); zbx_snprintf(sleeptext, sizeof(sleeptext), "idle for %d hour(s)", CONFIG_HOUSEKEEPING_FREQUENCY); } zbx_set_sigusr_handler(zbx_housekeeper_sigusr_handler); for (;;) { sec = zbx_time(); if (0 == CONFIG_HOUSEKEEPING_FREQUENCY) zbx_sleep_forever(); else zbx_sleep_loop(sleeptime); time_slept = zbx_time() - sec; hk_period = get_housekeeper_period(time_slept); start = time(NULL); zabbix_log(LOG_LEVEL_WARNING, "executing housekeeper"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); zbx_setproctitle("%s [removing old history]", get_process_type_string(process_type)); sec = zbx_time(); records = housekeeping_history(start); sec = zbx_time() - sec; DBclose(); zabbix_log(LOG_LEVEL_WARNING, "%s [deleted %d records in " ZBX_FS_DBL " sec, %s]", get_process_type_string(process_type), records, sec, sleeptext); zbx_setproctitle("%s [deleted %d records in " ZBX_FS_DBL " sec, %s]", get_process_type_string(process_type), records, sec, sleeptext); if (0 != CONFIG_HOUSEKEEPING_FREQUENCY) sleeptime = CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR; } }
/****************************************************************************** * * * Function: main_dbsyncer_loop * * * * Purpose: periodically synchronises data in memory cache with database * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_dbsyncer_loop() { int sleeptime, last_sleeptime = -1, num; double sec; int retry_up = 0, retry_dn = 0; zabbix_log(LOG_LEVEL_DEBUG, "In main_dbsyncer_loop() process_num:%d", process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [syncing history]", get_process_type_string(process_type)); zabbix_log(LOG_LEVEL_DEBUG, "Syncing ..."); sec = zbx_time(); num = DCsync_history(ZBX_SYNC_PARTIAL); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while processing %d items", get_process_type_string(process_type), process_num, sec, num); if (-1 == last_sleeptime) { sleeptime = num ? ZBX_SYNC_MAX / num : CONFIG_HISTSYNCER_FREQUENCY; } else { sleeptime = last_sleeptime; if (ZBX_SYNC_MAX < num) { retry_up = 0; retry_dn++; } else if (ZBX_SYNC_MAX / 2 > num) { retry_up++; retry_dn = 0; } else retry_up = retry_dn = 0; if (2 < retry_dn) { sleeptime--; retry_dn = 0; } if (2 < retry_up) { sleeptime++; retry_up = 0; } } if (0 > sleeptime) sleeptime = 0; else if (CONFIG_HISTSYNCER_FREQUENCY < sleeptime) sleeptime = CONFIG_HISTSYNCER_FREQUENCY; last_sleeptime = sleeptime; zbx_sleep_loop(sleeptime); } }