/****************************************************************************** * * * 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_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: ping_database * * * * Purpose: check availability of database * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static void ping_database() { zabbix_log(LOG_LEVEL_DEBUG, "In ping_database()"); /* This is test SQL query, it does nothing */ if(DBping() == FAIL) { zabbix_log(LOG_LEVEL_WARNING, "Watchdog: Database is down"); send_alerts(); } else { zabbix_log(LOG_LEVEL_DEBUG, "Watchdog: Database is up"); } }
/****************************************************************************** * * * Function: sync_config * * * * Purpose: sync list of medias to send notifications in case if DB is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ static void sync_config() { const char *__function_name = "sync_config"; DB_RESULT result; DB_ROW row; ZBX_RECIPIENT *recipient; int count = 0, old_count; static int no_recipients = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect_once("select 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,m.sendto" " from media m,users_groups u,config c,media_type mt" " where m.userid=u.userid" " and u.usrgrpid=c.alert_usrgrpid" " and m.mediatypeid=mt.mediatypeid" " and m.active=%d", MEDIA_STATUS_ACTIVE); if (NULL == result || (DB_RESULT)ZBX_DB_DOWN == result) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); goto exit; } old_count = recipients.values_num; while (NULL != (row = DBfetch(result))) { /* add the recipients to the list */ if (count >= recipients.values_num) { recipient = zbx_calloc(NULL, 1, sizeof(ZBX_RECIPIENT)); zbx_vector_ptr_append(&recipients, recipient); } else recipient = recipients.values[count]; ZBX_STR2UINT64(recipient->mediatype.mediatypeid, row[0]); recipient->mediatype.type = atoi(row[1]); /* the recipients are likely to be the same, change only what's different */ STR_REPLACE(recipient->mediatype.description, row[2]); STR_REPLACE(recipient->mediatype.smtp_server, row[3]); STR_REPLACE(recipient->mediatype.smtp_helo, row[4]); STR_REPLACE(recipient->mediatype.smtp_email, row[5]); STR_REPLACE(recipient->mediatype.exec_path, row[6]); STR_REPLACE(recipient->mediatype.gsm_modem, row[7]); STR_REPLACE(recipient->mediatype.username, row[8]); STR_REPLACE(recipient->mediatype.passwd, row[9]); STR_REPLACE(recipient->alert.sendto, row[10]); if (NULL == recipient->alert.subject) recipient->alert.message = recipient->alert.subject = zbx_strdup(NULL, "Zabbix database is down."); count++; } DBfree_result(result); if (0 < old_count && 0 == count) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: no recipients found for database down messages"); no_recipients = 1; } else if (1 == no_recipients && 0 < count) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: %d recipient(s) found for database down messages", count); no_recipients = 0; } recipients.values_num = count; while (count < old_count) { /* some recipients have been deleted, free the older entries */ recipient = recipients.values[count++]; zbx_free(recipient->mediatype.description); zbx_free(recipient->mediatype.smtp_server); zbx_free(recipient->mediatype.smtp_helo); zbx_free(recipient->mediatype.smtp_email); zbx_free(recipient->mediatype.exec_path); zbx_free(recipient->mediatype.gsm_modem); zbx_free(recipient->mediatype.username); zbx_free(recipient->mediatype.passwd); zbx_free(recipient->alert.sendto); zbx_free(recipient->alert.subject); zbx_free(recipient); } exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s() values_num:%d", __function_name, recipients.values_num); }