static void row2value_ui64(history_value_t *value, DB_ROW row) { ZBX_STR2UINT64(value->ui64, row[0]); }
static int get_dynamic_hostid(DB_EVENT *event, DC_HOST *host, char *error, size_t max_error_len) { const char *__function_name = "get_dynamic_hostid"; DB_RESULT result; DB_ROW row; char sql[512]; size_t offset; int ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); offset = zbx_snprintf(sql, sizeof(sql), "select distinct h.hostid,h.host"); #ifdef HAVE_OPENIPMI offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, ",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password"); #endif switch (event->source) { case EVENT_SOURCE_TRIGGERS: zbx_snprintf(sql + offset, sizeof(sql) - offset, " from functions f,items i,hosts h" " where f.itemid=i.itemid" " and i.hostid=h.hostid" " and h.status=%d" " and f.triggerid=" ZBX_FS_UI64, HOST_STATUS_MONITORED, event->objectid); break; case EVENT_SOURCE_DISCOVERY: offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, " from hosts h,interface i,dservices ds" " where h.hostid=i.hostid" " and i.ip=ds.ip" " and i.useip=1" " and h.status=%d", HOST_STATUS_MONITORED); switch (event->object) { case EVENT_OBJECT_DHOST: zbx_snprintf(sql + offset, sizeof(sql) - offset, " and ds.dhostid=" ZBX_FS_UI64 DB_NODE, event->objectid, DBnode_local("h.hostid")); break; case EVENT_OBJECT_DSERVICE: zbx_snprintf(sql + offset, sizeof(sql) - offset, " and ds.dserviceid=" ZBX_FS_UI64 DB_NODE, event->objectid, DBnode_local("h.hostid")); break; } break; case EVENT_SOURCE_AUTO_REGISTRATION: zbx_snprintf(sql + offset, sizeof(sql) - offset, " from autoreg_host a,hosts h" " where " ZBX_SQL_NULLCMP("a.proxy_hostid", "h.proxy_hostid") " and a.host=h.host" " and h.status=%d" " and a.autoreg_hostid=" ZBX_FS_UI64 DB_NODE, HOST_STATUS_MONITORED, event->objectid, DBnode_local("h.hostid")); break; default: zbx_snprintf(error, max_error_len, "Unsupported event source [%d]", event->source); return FAIL; } host->hostid = 0; result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { if (0 != host->hostid) { switch (event->source) { case EVENT_SOURCE_TRIGGERS: zbx_strlcpy(error, "Too many hosts in a trigger expression", max_error_len); break; case EVENT_SOURCE_DISCOVERY: zbx_strlcpy(error, "Too many hosts with same IP addresses", max_error_len); break; } ret = FAIL; break; } ZBX_STR2UINT64(host->hostid, row[0]); strscpy(host->host, row[1]); #ifdef HAVE_OPENIPMI host->ipmi_authtype = (signed char)atoi(row[2]); host->ipmi_privilege = (unsigned char)atoi(row[3]); strscpy(host->ipmi_username, row[4]); strscpy(host->ipmi_password, row[5]); #endif } DBfree_result(result); if (FAIL == ret) { host->hostid = 0; *host->host = '\0'; } else if (0 == host->hostid) { *host->host = '\0'; zbx_strlcpy(error, "Cannot find a corresponding host", max_error_len); ret = FAIL; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static void add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action, zbx_uint64_t userid, zbx_uint64_t mediatypeid, const char *subject, const char *message) { const char *__function_name = "add_message_alert"; DB_RESULT result; DB_ROW row; zbx_uint64_t alertid; int now, severity, medias = 0; char *subject_dyn, *message_dyn, *sendto_esc, *subject_esc, *message_esc, *error_esc; char error[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); subject_dyn = zbx_strdup(NULL, subject); message_dyn = zbx_strdup(NULL, message); substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &subject_dyn, MACRO_TYPE_MESSAGE, NULL, 0); substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &message_dyn, MACRO_TYPE_MESSAGE, NULL, 0); now = time(NULL); subject_esc = DBdyn_escape_string_len(subject_dyn, ALERT_SUBJECT_LEN); message_esc = DBdyn_escape_string_len(message_dyn, ALERT_MESSAGE_LEN); zbx_free(subject_dyn); zbx_free(message_dyn); if (0 == mediatypeid) { result = DBselect( "select m.mediatypeid,m.sendto,m.severity,m.period,mt.status" " from media m,media_type mt" " where m.mediatypeid=mt.mediatypeid" " and m.active=%d" " and m.userid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid); } else { result = DBselect( "select m.mediatypeid,m.sendto,m.severity,m.period,mt.status" " from media m,media_type mt" " where m.mediatypeid=mt.mediatypeid" " and m.active=%d" " and m.userid=" ZBX_FS_UI64 " and m.mediatypeid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid, mediatypeid); } while (NULL != (row = DBfetch(result))) { medias = 1; ZBX_STR2UINT64(mediatypeid, row[0]); severity = atoi(row[2]); zabbix_log(LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]", (int)event->trigger.priority, severity, row[3]); if (((1 << event->trigger.priority) & severity) == 0) { zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (severity)"); continue; } if (FAIL == check_time_period(row[3], (time_t)NULL)) { zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (period)"); continue; } alertid = DBget_maxid("alerts"); sendto_esc = DBdyn_escape_string_len(row[1], ALERT_SENDTO_LEN); if (MEDIA_TYPE_STATUS_ACTIVE == atoi(row[4])) { DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock" ",mediatypeid,sendto,subject,message,status,alerttype,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d" "," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)", alertid, action->actionid, event->eventid, userid, now, mediatypeid, sendto_esc, subject_esc, message_esc, ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE, escalation->esc_step); } else { error_esc = DBdyn_escape_string("Media type disabled"); DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock" ",mediatypeid,sendto,subject,message,status,alerttype,esc_step,error)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d" "," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d,'%s')", alertid, action->actionid, event->eventid, userid, now, mediatypeid, sendto_esc, subject_esc, message_esc, ALERT_STATUS_FAILED, ALERT_TYPE_MESSAGE, escalation->esc_step, error_esc); zbx_free(error_esc); } zbx_free(sendto_esc); } DBfree_result(result); if (0 == medias) { zbx_snprintf(error, sizeof(error), "No media defined for user \"%s\"", zbx_user_string(userid)); alertid = DBget_maxid("alerts"); error_esc = DBdyn_escape_string(error); DBexecute("insert into alerts (alertid,actionid,eventid,userid,retries,clock" ",subject,message,status,alerttype,error,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d" ",'%s','%s',%d,%d,'%s',%d)", alertid, action->actionid, event->eventid, userid, ALERT_MAX_RETRIES, now, subject_esc, message_esc, ALERT_STATUS_FAILED, ALERT_TYPE_MESSAGE, error_esc, escalation->esc_step); zbx_free(error_esc); } zbx_free(subject_esc); zbx_free(message_esc); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: add host if not added already * * * * Purpose: add discovered host * * * * Parameters: dhostid - discovered host id * * * * Return value: hostid - new/existing hostid * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static zbx_uint64_t add_discovered_host(DB_EVENT *event) { const char *__function_name = "add_discovered_host"; DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; zbx_uint64_t hostid = 0, proxy_hostid, host_proxy_hostid; char host[MAX_STRING_LEN], *host_esc, *ip_esc, *host_unique, *host_unique_esc; int port; zbx_uint64_t groupid; zabbix_log(LOG_LEVEL_DEBUG, "In %s(eventid:" ZBX_FS_UI64 ")", __function_name, event->eventid); result = DBselect( "select discovery_groupid" " from config" " where 1=1" DB_NODE, DBnode_local("configid")); if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(groupid, row[0]); } else { zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined"); return 0; } DBfree_result(result); switch (event->object) { case EVENT_OBJECT_DHOST: result = DBselect( "select dr.proxy_hostid,ds.ip" " from drules dr,dchecks dc,dservices ds" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds.dhostid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); break; case EVENT_OBJECT_DSERVICE: result = DBselect( "select dr.proxy_hostid,ds.ip" " from drules dr,dchecks dc,dservices ds,dservices ds1" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds1.dhostid=ds.dhostid" " and ds1.dserviceid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); break; case EVENT_OBJECT_ZABBIX_ACTIVE: result = DBselect("select proxy_hostid,host from autoreg_host" " where autoreg_hostid=" ZBX_FS_UI64, event->objectid); break; default: return 0; } if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(proxy_hostid, row[0]); if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object) { char sql[512]; host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN); zbx_snprintf(sql, sizeof(sql), "select hostid,proxy_hostid" " from hosts" " where host='%s'" DB_NODE " order by hostid", host_esc, DBnode_local("hostid")); result2 = DBselectN(sql, 1); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,dns)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',0,'%s')", hostid, proxy_hostid, host_esc, host_esc); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_STR2UINT64(host_proxy_hostid, row2[1]); if (host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set proxy_hostid=" ZBX_FS_UI64 " where hostid=" ZBX_FS_UI64, proxy_hostid, hostid); } } DBfree_result(result2); zbx_free(host_esc); } else /* EVENT_OBJECT_DHOST, EVENT_OBJECT_DSERVICE */ { alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(row[1], host, sizeof(host)); alarm(0); host_esc = DBdyn_escape_string_len(host, HOST_HOST_LEN); ip_esc = DBdyn_escape_string_len(row[1], HOST_IP_LEN); port = get_discovered_agent_port(event); result2 = DBselect( "select hostid,dns,port,proxy_hostid" " from hosts" " where ip='%s'" DB_NODE, ip_esc, DBnode_local("hostid")); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); /* for host uniqueness purposes */ if ('\0' != *host) { /* by host name */ make_hostname(host); /* replace not-allowed characters */ host_unique = DBget_unique_hostname_by_sample(host); } else { /* by ip */ make_hostname(row[1]); /* replace not-allowed characters */ host_unique = DBget_unique_hostname_by_sample(row[1]); } host_unique_esc = DBdyn_escape_string(host_unique); DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,ip,dns,port)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',1,'%s','%s',%d)", hostid, proxy_hostid, host_unique_esc, ip_esc, host_esc, port); zbx_free(host_unique); zbx_free(host_unique_esc); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_STR2UINT64(host_proxy_hostid, row2[3]); if (0 != strcmp(host, row2[1]) || host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set dns='%s',proxy_hostid=" ZBX_FS_UI64 " where hostid=" ZBX_FS_UI64, host_esc, proxy_hostid, hostid); } } DBfree_result(result2); zbx_free(host_esc); zbx_free(ip_esc); } } DBfree_result(result); if (0 != hostid) add_discovered_host_group(hostid, groupid); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return hostid; }
static void execute_escalation(DB_ESCALATION *escalation) { const char *__function_name = "execute_escalation"; DB_RESULT result; DB_ROW row; DB_ACTION action; DB_EVENT event; char *error = NULL; int source = (-1); zabbix_log(LOG_LEVEL_DEBUG, "In %s() escalationid:" ZBX_FS_UI64 " status:%s", __function_name, escalation->escalationid, zbx_escalation_status_string(escalation->status)); result = DBselect("select source from events where eventid=" ZBX_FS_UI64, escalation->eventid); if (NULL == (row = DBfetch(result))) error = zbx_dsprintf(error, "event [" ZBX_FS_UI64 "] deleted.", escalation->eventid); else source = atoi(row[0]); DBfree_result(result); if (NULL == error && EVENT_SOURCE_TRIGGERS == source) { /* trigger disabled? */ result = DBselect("select description,status from triggers where triggerid=" ZBX_FS_UI64, escalation->triggerid); if (NULL == (row = DBfetch(result))) error = zbx_dsprintf(error, "trigger [" ZBX_FS_UI64 "] deleted.", escalation->triggerid); else if (TRIGGER_STATUS_DISABLED == atoi(row[1])) error = zbx_dsprintf(error, "trigger '%s' disabled.", row[0]); DBfree_result(result); } if (NULL == error && EVENT_SOURCE_TRIGGERS == source) { /* item disabled? */ result = DBselect( "select i.name" " from items i,functions f,triggers t" " where i.itemid=f.itemid" " and f.triggerid=t.triggerid" " and t.triggerid=" ZBX_FS_UI64 " and i.status=%d", escalation->triggerid, ITEM_STATUS_DISABLED); if (NULL != (row = DBfetch(result))) error = zbx_dsprintf(error, "item '%s' disabled.", row[0]); DBfree_result(result); } if (NULL == error && EVENT_SOURCE_TRIGGERS == source) { /* host disabled? */ result = DBselect( "select h.host" " from hosts h,items i,functions f,triggers t" " where h.hostid=i.hostid" " and i.itemid=f.itemid" " and f.triggerid=t.triggerid" " and t.triggerid=" ZBX_FS_UI64 " and h.status=%d", escalation->triggerid, HOST_STATUS_NOT_MONITORED); if (NULL != (row = DBfetch(result))) error = zbx_dsprintf(error, "host '%s' disabled.", row[0]); DBfree_result(result); } switch (escalation->status) { case ESCALATION_STATUS_ACTIVE: result = DBselect( "select actionid,eventsource,esc_period,def_shortdata,def_longdata," "recovery_msg,status,name" " from actions" " where actionid=" ZBX_FS_UI64, escalation->actionid); break; case ESCALATION_STATUS_RECOVERY: result = DBselect( "select actionid,eventsource,esc_period,r_shortdata,r_longdata,recovery_msg," "status,name" " from actions" " where actionid=" ZBX_FS_UI64, escalation->actionid); break; default: THIS_SHOULD_NEVER_HAPPEN; return; } if (NULL != (row = DBfetch(result))) { memset(&action, 0, sizeof(action)); ZBX_STR2UINT64(action.actionid, row[0]); action.eventsource = atoi(row[1]); action.esc_period = atoi(row[2]); action.shortdata = row[3]; action.recovery_msg = atoi(row[5]); if (ACTION_STATUS_ACTIVE != atoi(row[6])) error = zbx_dsprintf(error, "action '%s' disabled.", row[7]); if (NULL != error) { action.longdata = zbx_dsprintf(action.longdata, "NOTE: Escalation cancelled: %s\n%s", error, row[4]); } else action.longdata = row[4]; switch (escalation->status) { case ESCALATION_STATUS_ACTIVE: if (SUCCEED == get_event_info(escalation->eventid, &event)) execute_operations(escalation, &event, &action); free_event_info(&event); break; case ESCALATION_STATUS_RECOVERY: if (SUCCEED == get_event_info(escalation->r_eventid, &event)) process_recovery_msg(escalation, &event, &action); free_event_info(&event); break; default: break; } if (NULL != error) zbx_free(action.longdata); } else error = zbx_dsprintf(error, "action [" ZBX_FS_UI64 "] deleted", escalation->actionid); DBfree_result(result); if (NULL != error) { escalation->status = ESCALATION_STATUS_COMPLETED; zabbix_log(LOG_LEVEL_WARNING, "escalation cancelled: %s", error); zbx_free(error); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action, zbx_uint64_t userid, zbx_uint64_t mediatypeid, char *subject, char *message) { DB_RESULT result; DB_ROW row; zbx_uint64_t alertid; int now, severity, medias = 0; char *sendto_esc, *subject_esc, *message_esc, *error_esc; char error[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In add_message_alert()"); /* zabbix_log(LOG_LEVEL_DEBUG,"MESSAGE\n\tuserid : " ZBX_FS_UI64 "\n\tsubject: %s\n\tmessage: %s", userid, subject, message);*/ now = time(NULL); subject_esc = DBdyn_escape_string_len(subject, ALERT_SUBJECT_LEN); message_esc = DBdyn_escape_string(message); if (0 == mediatypeid) { result = DBselect("select mediatypeid,sendto,severity,period from media" " where active=%d and userid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid); } else { result = DBselect("select mediatypeid,sendto,severity,period from media" " where active=%d and userid=" ZBX_FS_UI64 " and mediatypeid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid, mediatypeid); } while (NULL != (row = DBfetch(result))) { medias = 1; ZBX_STR2UINT64(mediatypeid, row[0]); severity = atoi(row[2]); zabbix_log( LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]", event->trigger_priority, severity, row[3]); if (((1 << event->trigger_priority) & severity) == 0) { zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (severity)"); continue; } if (check_time_period(row[3], (time_t)NULL) == 0) { zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (period)"); continue; } alertid = DBget_maxid("alerts", "alertid"); sendto_esc = DBdyn_escape_string_len(row[1], ALERT_SENDTO_LEN); DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock" ",mediatypeid,sendto,subject,message,status,alerttype,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d" "," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)", alertid, action->actionid, event->eventid, userid, now, mediatypeid, sendto_esc, subject_esc, message_esc, ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE, escalation->esc_step); zbx_free(sendto_esc); } DBfree_result(result); if (0 == medias) { zbx_snprintf(error, sizeof(error), "No media defined for user \"%s\"", zbx_user_string(userid)); alertid = DBget_maxid("alerts", "alertid"); error_esc = DBdyn_escape_string(error); DBexecute("insert into alerts (alertid,actionid,eventid,userid,retries,clock" ",subject,message,status,alerttype,error,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d" ",'%s','%s',%d,%d,'%s',%d)", alertid, action->actionid, event->eventid, userid, ALERT_MAX_RETRIES, now, subject_esc, message_esc, ALERT_STATUS_FAILED, ALERT_TYPE_MESSAGE, error_esc, escalation->esc_step); zbx_free(error_esc); } zbx_free(subject_esc); zbx_free(message_esc); }
static void execute_escalation(DB_ESCALATION *escalation) { DB_RESULT result; DB_ROW row; DB_ACTION action; DB_EVENT event; char *error = NULL; int source; result = DBselect("select source from events where eventid=" ZBX_FS_UI64, escalation->eventid); if (NULL == (row = DBfetch(result))) error = zbx_dsprintf(error, "Event [" ZBX_FS_UI64 "] deleted.", escalation->eventid); else source = atoi(row[0]); DBfree_result(result); if (NULL == error && EVENT_SOURCE_TRIGGERS == source) { /* Trigger disabled? */ result = DBselect("select description,status from triggers where triggerid=" ZBX_FS_UI64, escalation->triggerid); if (NULL == (row = DBfetch(result))) error = zbx_dsprintf(error, "Trigger [" ZBX_FS_UI64 "] deleted.", escalation->triggerid); else if (TRIGGER_STATUS_DISABLED == atoi(row[1])) error = zbx_dsprintf(error, "Trigger '%s' disabled.", row[0]); DBfree_result(result); } if (NULL == error && EVENT_SOURCE_TRIGGERS == source) { /* Item disabled? */ result = DBselect("select i.description from items i,functions f,triggers t" " where t.triggerid=" ZBX_FS_UI64 " and f.triggerid=t.triggerid" " and i.itemid=f.itemid and i.status=%d", escalation->triggerid, ITEM_STATUS_DISABLED); if (NULL != (row = DBfetch(result))) error = zbx_dsprintf(error, "Item '%s' disabled.", row[0]); DBfree_result(result); } if (NULL == error && EVENT_SOURCE_TRIGGERS == source) { /* Host disabled? */ result = DBselect("select h.host from hosts h,items i,functions f,triggers t" " where t.triggerid=" ZBX_FS_UI64 " and t.triggerid=f.triggerid" " and f.itemid=i.itemid and i.hostid=h.hostid and h.status=%d", escalation->triggerid, HOST_STATUS_NOT_MONITORED); if (NULL != (row = DBfetch(result))) error = zbx_dsprintf(error, "Host '%s' disabled.", row[0]); DBfree_result(result); } switch (escalation->status) { case ESCALATION_STATUS_ACTIVE: result = DBselect("select actionid,eventsource,esc_period,def_shortdata,def_longdata,recovery_msg,status,name" " from actions where actionid=" ZBX_FS_UI64, escalation->actionid); break; case ESCALATION_STATUS_RECOVERY: result = DBselect("select actionid,eventsource,esc_period,r_shortdata,r_longdata,recovery_msg,status,name" " from actions where actionid=" ZBX_FS_UI64, escalation->actionid); break; default: /* Never reached */ return; } if (NULL != (row = DBfetch(result))) { memset(&action, 0, sizeof(action)); ZBX_STR2UINT64(action.actionid, row[0]); action.eventsource = atoi(row[1]); action.esc_period = atoi(row[2]); action.shortdata = strdup(row[3]); action.recovery_msg = atoi(row[5]); if (ACTION_STATUS_ACTIVE != atoi(row[6])) error = zbx_dsprintf(error, "Action '%s' disabled.", row[7]); if (NULL != error) action.longdata = zbx_dsprintf(action.longdata, "NOTE: Escalation cancelled: %s\n%s", error, row[4]); else action.longdata = strdup(row[4]); switch (escalation->status) { case ESCALATION_STATUS_ACTIVE: if (SUCCEED == get_event_info(escalation->eventid, &event)) { substitute_macros(&event, &action, NULL, &action.shortdata); substitute_macros(&event, &action, NULL, &action.longdata); execute_operations(escalation, &event, &action); } free_event_info(&event); break; case ESCALATION_STATUS_RECOVERY: if (SUCCEED == get_event_info(escalation->r_eventid, &event)) { substitute_macros(&event, &action, escalation, &action.shortdata); substitute_macros(&event, &action, escalation, &action.longdata); process_recovery_msg(escalation, &event, &action); } free_event_info(&event); break; default: break; } zbx_free(action.shortdata); zbx_free(action.longdata); } else error = zbx_dsprintf(error, "Action [" ZBX_FS_UI64 "] deleted", escalation->actionid); DBfree_result(result); if (NULL != error) { escalation->status = ESCALATION_STATUS_COMPLETED; zabbix_log(LOG_LEVEL_WARNING, "Escalation cancelled: %s", error); zbx_free(error); } }
/****************************************************************************** * * * Function: process_record * * * * Purpose: process record update * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_record(int nodeid, const char *record, int sender_nodetype) { char fieldname[ZBX_FIELDNAME_LEN_MAX]; zbx_uint64_t recid; int op, res = SUCCEED; int valuetype; char *value_esc; const ZBX_TABLE *table; DB_RESULT result; DB_ROW row; const char *r; char *buffer = NULL, *tmp = NULL, *fields_update = NULL, *fields = NULL, *values = NULL; int buffer_allocated = 16*1024, buffer_len, fieldname_len; int tmp_allocated = 16*1024, tmp_offset = 0; int fields_update_allocated = 16*1024, fields_update_offset = 0; int fields_allocated = 4*1024, fields_offset = 0; int values_allocated = 16*1024, values_offset = 0; zabbix_log( LOG_LEVEL_DEBUG, "In process_record [%s]", record); r = record; buffer = zbx_malloc(buffer, buffer_allocated); zbx_get_next_field(&r, &buffer, &buffer_allocated, ZBX_DM_DELIMITER); if (NULL == (table = DBget_table(buffer))) { zabbix_log(LOG_LEVEL_WARNING, "Cannot find table [%s]", buffer); res = FAIL; goto out; } zbx_get_next_field(&r, &buffer, &buffer_allocated, ZBX_DM_DELIMITER); ZBX_STR2UINT64(recid, buffer); zbx_get_next_field(&r, &buffer, &buffer_allocated, ZBX_DM_DELIMITER); op = atoi(buffer); if (op == NODE_CONFIGLOG_OP_DELETE) { DBexecute("delete from %s where %s=" ZBX_FS_UI64, table->table, table->recid, recid); goto out; } tmp = zbx_malloc(tmp, tmp_allocated); fields_update = zbx_malloc(fields_update, fields_update_allocated); fields = zbx_malloc(fields, fields_allocated); values = zbx_malloc(values, values_allocated); zbx_snprintf_alloc(&fields, &fields_allocated, &fields_offset, 128, "%s,", table->recid); zbx_snprintf_alloc(&values, &values_allocated, &values_offset, 128, ZBX_FS_UI64",", recid); while (NULL != r) { fieldname_len = zbx_get_next_field(&r, &buffer, &buffer_allocated, ZBX_DM_DELIMITER); zbx_strlcpy(fieldname, buffer, sizeof(fieldname)); zbx_get_next_field(&r, &buffer, &buffer_allocated, ZBX_DM_DELIMITER); valuetype=atoi(buffer); buffer_len = zbx_get_next_field(&r, &buffer, &buffer_allocated, ZBX_DM_DELIMITER); if (op == NODE_CONFIGLOG_OP_UPDATE) { if (0 == strcmp(buffer, "NULL")) { zbx_snprintf_alloc(&fields_update, &fields_update_allocated, &fields_update_offset, fieldname_len + 8, "%s=NULL,", fieldname); zbx_snprintf_alloc(&values, &values_allocated, &values_offset, 8, "NULL,"); } else { if (valuetype == ZBX_TYPE_INT || valuetype == ZBX_TYPE_UINT || valuetype == ZBX_TYPE_ID || valuetype == ZBX_TYPE_FLOAT) { zbx_snprintf_alloc(&fields_update, &fields_update_allocated, &fields_update_offset, fieldname_len + buffer_len + 4, "%s=%s,", fieldname, buffer); zbx_snprintf_alloc(&values, &values_allocated, &values_offset, buffer_len + 4, "%s,", buffer); } else if (valuetype == ZBX_TYPE_BLOB) { if (*buffer == '\0') { zbx_snprintf_alloc(&fields_update, &fields_update_allocated, &fields_update_offset, fieldname_len + 8, "%s='',", fieldname); zbx_snprintf_alloc(&values, &values_allocated, &values_offset, 8, "'',"); } else { #if defined(HAVE_POSTGRESQL) buffer_len = zbx_hex2binary(buffer); buffer_len = zbx_pg_escape_bytea((u_char *)buffer, buffer_len, &tmp, &tmp_allocated); zbx_snprintf_alloc(&fields_update, &fields_update_allocated, &fields_update_offset, fieldname_len + buffer_len + 8, "%s='%s',", fieldname, tmp); zbx_snprintf_alloc(&values, &values_allocated, &values_offset, buffer_len + 8, "'%s',", tmp); #else zbx_snprintf_alloc(&fields_update, &fields_update_allocated, &fields_update_offset, fieldname_len + buffer_len + 8, "%s=0x%s,", fieldname, buffer); zbx_snprintf_alloc(&values, &values_allocated, &values_offset, buffer_len + 8, "0x%s,", buffer); #endif } } else /* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */ { zbx_hex2binary(buffer); value_esc = DBdyn_escape_string(buffer); buffer_len = strlen(value_esc); zbx_snprintf_alloc(&fields_update, &fields_update_allocated, &fields_update_offset, fieldname_len + buffer_len + 8, "%s='%s',", fieldname, value_esc); zbx_snprintf_alloc(&values, &values_allocated, &values_offset, buffer_len + 8, "'%s',", value_esc); zbx_free(value_esc) } } zbx_snprintf_alloc(&fields, &fields_allocated, &fields_offset, fieldname_len + 4, "%s,", fieldname); } else { zabbix_log( LOG_LEVEL_WARNING, "Unknown record operation [%d]", op); res = FAIL; goto out; } }
static void process_test_data(zbx_uint64_t httptestid, int lastfailedstep, double speed_download, const char *err_str, zbx_timespec_t *ts) { const char *__function_name = "process_test_data"; DB_RESULT result; DB_ROW row; unsigned char types[3], states[3]; DC_ITEM items[3]; zbx_uint64_t itemids[3]; int lastclocks[3], errcodes[3]; size_t i, num = 0; AGENT_RESULT value; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect("select type,itemid from httptestitem where httptestid=" ZBX_FS_UI64, httptestid); while (NULL != (row = DBfetch(result))) { if (3 == num) { THIS_SHOULD_NEVER_HAPPEN; break; } switch (types[num] = (unsigned char)atoi(row[0])) { case ZBX_HTTPITEM_TYPE_SPEED: case ZBX_HTTPITEM_TYPE_LASTSTEP: break; case ZBX_HTTPITEM_TYPE_LASTERROR: if (NULL == err_str) continue; break; default: THIS_SHOULD_NEVER_HAPPEN; continue; } ZBX_STR2UINT64(itemids[num], row[1]); num++; } DBfree_result(result); DCconfig_get_items_by_itemids(items, itemids, errcodes, num); for (i = 0; i < num; i++) { if (SUCCEED != errcodes[i]) continue; if (HOST_MAINTENANCE_STATUS_ON == items[i].host.maintenance_status && MAINTENANCE_TYPE_NODATA == items[i].host.maintenance_type) { continue; } init_result(&value); switch (types[i]) { case ZBX_HTTPITEM_TYPE_SPEED: SET_UI64_RESULT(&value, speed_download); break; case ZBX_HTTPITEM_TYPE_LASTSTEP: SET_UI64_RESULT(&value, lastfailedstep); break; case ZBX_HTTPITEM_TYPE_LASTERROR: SET_STR_RESULT(&value, zbx_strdup(NULL, err_str)); break; } items[i].state = ITEM_STATE_NORMAL; dc_add_history(items[i].itemid, items[i].value_type, 0, &value, ts, items[i].state, NULL); states[i] = items[i].state; lastclocks[i] = ts->sec; free_result(&value); } DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num); DCconfig_clean_items(items, errcodes, num); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: process_record * * * * Purpose: process record update * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_record(char **sql, size_t *sql_alloc, size_t *sql_offset, int sender_nodeid, int nodeid, const ZBX_TABLE *table, const char *record, int lastrecord, int acknowledges, zbx_vector_uint64_t *ack_eventids) { const char *r; int f, res = FAIL; char *value_esc; zabbix_log(LOG_LEVEL_DEBUG, "In process_record()"); if (0 == *sql_offset) { DBbegin_multiple_update(sql, sql_alloc, sql_offset); #ifdef HAVE_MULTIROW_INSERT begin_history_sql(sql, sql_alloc, sql_offset, table); #endif } #if !defined(HAVE_MULTIROW_INSERT) begin_history_sql(sql, sql_alloc, sql_offset, table); #endif zbx_chrcpy_alloc(sql, sql_alloc, sql_offset, '('); if (0 != (table->flags & ZBX_HISTORY_SYNC)) zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%d,", nodeid); for (r = record, f = 0; table->fields[f].name != 0; f++) { if (0 != (table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; if (NULL == r) goto error; zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); if (0 != acknowledges && 0 == strcmp(table->fields[f].name, "eventid")) { zbx_uint64_t eventid; ZBX_STR2UINT64(eventid, buffer); zbx_vector_uint64_append(ack_eventids, eventid); } if (table->fields[f].type == ZBX_TYPE_INT || table->fields[f].type == ZBX_TYPE_UINT || table->fields[f].type == ZBX_TYPE_ID || table->fields[f].type == ZBX_TYPE_FLOAT) { zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%s,", buffer); } else if (table->fields[f].type == ZBX_TYPE_BLOB) { if ('\0' == *buffer) zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "'',"); else { #ifdef HAVE_POSTGRESQL size_t len; len = zbx_hex2binary(buffer); zbx_pg_escape_bytea((u_char *)buffer, len, &tmp, &tmp_alloc); zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "'%s',", tmp); #else zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "0x%s,", buffer); #endif } } else /* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */ { zbx_hex2binary(buffer); value_esc = DBdyn_escape_string(buffer); zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "'%s',", value_esc); zbx_free(value_esc); } } (*sql_offset)--; #ifdef HAVE_MULTIROW_INSERT zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "),"); #else zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ");\n"); #endif if (0 != lastrecord || *sql_offset > ZBX_MAX_SQL_SIZE) { #ifdef HAVE_MULTIROW_INSERT (*sql_offset)--; zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n"); #endif DBend_multiple_update(sql, sql_alloc, sql_offset); if (ZBX_DB_OK <= DBexecute("%s", *sql)) res = SUCCEED; *sql_offset = 0; if (SUCCEED == res && 0 != lastrecord && 0 != acknowledges && 0 != ack_eventids->values_num) { zbx_vector_uint64_sort(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_uint64_uniq(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "update events" " set acknowledged=1" " where"); DBadd_condition_alloc(sql, sql_alloc, sql_offset, "eventid", ack_eventids->values, ack_eventids->values_num); if (ZBX_DB_OK > DBexecute("%s", *sql)) res = FAIL; *sql_offset = 0; } } else res = SUCCEED; return res; error: zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received invalid record from node %d for node %d [%s]", CONFIG_NODEID, sender_nodeid, nodeid, record); return FAIL; }
/****************************************************************************** * * * Function: update_items * * * * Purpose: process record update * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: * * * * Comments: * * * ******************************************************************************/ static int process_items(char **sql, size_t *sql_alloc, size_t *sql_offset, int sender_nodeid, int nodeid, const ZBX_TABLE *table, const char *record, int lastrecord) { const char *r; int f, res = FAIL; zbx_uint64_t itemid = 0; char *value_esc; int clock, value_type = -1; double value_double; zbx_uint64_t value_uint64; zabbix_log(LOG_LEVEL_DEBUG, "In process_items()"); if (*sql_offset == 0) DBbegin_multiple_update(sql, sql_alloc, sql_offset); zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "update items set prevvalue=lastvalue"); for (r = record, f = 0; table->fields[f].name != 0; f++) { if (0 != (table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; if (NULL == r) goto error; zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); if (0 == strcmp(table->fields[f].name, "itemid")) ZBX_STR2UINT64(itemid, buffer); if (table->fields[f].type == ZBX_TYPE_INT || table->fields[f].type == ZBX_TYPE_UINT || table->fields[f].type == ZBX_TYPE_ID || table->fields[f].type == ZBX_TYPE_FLOAT) { if (0 == strcmp(table->fields[f].name, "clock")) { zbx_snprintf_alloc(sql, sql_alloc, sql_offset, ",lastclock=%s", buffer); clock = atoi(buffer); } else if (0 == strcmp(table->fields[f].name, "value")) { zbx_snprintf_alloc(sql, sql_alloc, sql_offset, ",lastvalue=%s", buffer); value_type = table->fields[f].type; if (value_type == ZBX_TYPE_FLOAT) value_double = atof(buffer); else if (value_type == ZBX_TYPE_UINT) ZBX_STR2UINT64(value_uint64, buffer); } } else /* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */ { if (0 == strcmp(table->fields[f].name, "value")) { zbx_hex2binary(buffer); value_esc = DBdyn_escape_string_len(buffer, ITEM_LASTVALUE_LEN); zbx_snprintf_alloc(sql, sql_alloc, sql_offset, ",lastvalue='%s'", value_esc); zbx_free(value_esc); } } } if (value_type == ZBX_TYPE_FLOAT) DBadd_trend(itemid, value_double, clock); else if (value_type == ZBX_TYPE_UINT) DBadd_trend_uint(itemid, value_uint64, clock); zbx_snprintf_alloc(sql, sql_alloc, sql_offset, " where itemid=" ZBX_FS_UI64 ";\n", itemid); if (lastrecord || *sql_offset > ZBX_MAX_SQL_SIZE) { DBend_multiple_update(sql, sql_alloc, sql_offset); if (DBexecute("%s", *sql) >= ZBX_DB_OK) res = SUCCEED; *sql_offset = 0; } else res = SUCCEED; return res; error: zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received invalid record from node %d for node %d [%s]", CONFIG_NODEID, sender_nodeid, nodeid, record); return FAIL; }
/****************************************************************************** * * * Function: delete_history * * * * Purpose: remove outdated information from historical table * * * * Parameters: now - current timestamp * * * * Return value: number of rows records * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int delete_history(const char *table, const char *fieldname, int now) { const char *__function_name = "delete_history"; DB_RESULT result; DB_ROW row; int minclock, records = 0; zbx_uint64_t lastid, maxid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' now:%d", __function_name, table, now); DBbegin(); result = DBselect( "select nextid" " from ids" " where table_name='%s'" " and field_name='%s'", table, fieldname); if (NULL == (row = DBfetch(result))) goto rollback; ZBX_STR2UINT64(lastid, row[0]); DBfree_result(result); result = DBselect("select min(clock) from %s", table); if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0])) goto rollback; minclock = atoi(row[0]); DBfree_result(result); result = DBselect("select max(id) from %s", table); if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0])) goto rollback; ZBX_STR2UINT64(maxid, row[0]); DBfree_result(result); records = DBexecute( "delete from %s" " where id<" ZBX_FS_UI64 " and (clock<%d" " or (id<=" ZBX_FS_UI64 " and clock<%d))", table, maxid, now - CONFIG_PROXY_OFFLINE_BUFFER * SEC_PER_HOUR, lastid, MIN(now - CONFIG_PROXY_LOCAL_BUFFER * SEC_PER_HOUR, minclock + HK_MAX_DELETE_PERIODS * hk_period)); DBcommit(); return records; rollback: DBfree_result(result); DBrollback(); return 0; }
/****************************************************************************** * * * Function: lld_process_discovery_rule * * * * Purpose: add or update items, triggers and graphs for discovery item * * * * Parameters: lld_ruleid - [IN] discovery item identificator from database * * value - [IN] received value from agent * * * ******************************************************************************/ void lld_process_discovery_rule(zbx_uint64_t lld_ruleid, char *value, zbx_timespec_t *ts) { const char *__function_name = "lld_process_discovery_rule"; DB_RESULT result; DB_ROW row; zbx_uint64_t hostid = 0; char *discovery_key = NULL, *filter = NULL, *error = NULL, *db_error = NULL, *error_esc; unsigned char state = 0; unsigned short lifetime; zbx_vector_ptr_t lld_rows; char *sql = NULL; size_t sql_alloc = 128, sql_offset = 0; const char *sql_start = "update items set ", *sql_continue = ","; zabbix_log(LOG_LEVEL_DEBUG, "In %s() itemid:" ZBX_FS_UI64, __function_name, lld_ruleid); zbx_vector_ptr_create(&lld_rows); sql = zbx_malloc(sql, sql_alloc); result = DBselect( "select hostid,key_,state,filter,error,lifetime" " from items" " where itemid=" ZBX_FS_UI64, lld_ruleid); if (NULL != (row = DBfetch(result))) { char *lifetime_str; ZBX_STR2UINT64(hostid, row[0]); discovery_key = zbx_strdup(discovery_key, row[1]); state = (unsigned char)atoi(row[2]); filter = zbx_strdup(filter, row[3]); db_error = zbx_strdup(db_error, row[4]); lifetime_str = zbx_strdup(NULL, row[5]); substitute_simple_macros(NULL, NULL, NULL, NULL, &hostid, NULL, NULL, &lifetime_str, MACRO_TYPE_COMMON, NULL, 0); if (SUCCEED != is_ushort(lifetime_str, &lifetime)) { zabbix_log(LOG_LEVEL_WARNING, "cannot process lost resources for the discovery rule \"%s:%s\":" " \"%s\" is not a valid value", zbx_host_string(hostid), discovery_key, lifetime_str); lifetime = 3650; /* max value for the field */ } zbx_free(lifetime_str); } else zabbix_log(LOG_LEVEL_WARNING, "invalid discovery rule ID [" ZBX_FS_UI64 "]", lld_ruleid); DBfree_result(result); if (0 == hostid) goto clean; if (SUCCEED != lld_rows_get(value, filter, &lld_rows, &error)) goto error; error = zbx_strdup(error, ""); lld_update_items(hostid, lld_ruleid, &lld_rows, &error, lifetime, ts->sec); lld_update_triggers(hostid, lld_ruleid, &lld_rows, &error); lld_update_graphs(hostid, lld_ruleid, &lld_rows, &error); lld_update_hosts(lld_ruleid, &lld_rows, &error, lifetime, ts->sec); if (ITEM_STATE_NOTSUPPORTED == state) { zabbix_log(LOG_LEVEL_WARNING, "discovery rule [" ZBX_FS_UI64 "][%s] became supported", lld_ruleid, zbx_host_key_string(lld_ruleid)); add_event(0, EVENT_SOURCE_INTERNAL, EVENT_OBJECT_LLDRULE, lld_ruleid, ts, ITEM_STATE_NORMAL, NULL, NULL, 0, 0); process_events(); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sstate=%d", sql_start, ITEM_STATE_NORMAL); sql_start = sql_continue; } error: if (NULL != error && 0 != strcmp(error, db_error)) { error_esc = DBdyn_escape_string_len(error, ITEM_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%serror='%s'", sql_start, error_esc); sql_start = sql_continue; zbx_free(error_esc); } if (sql_start == sql_continue) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where itemid=" ZBX_FS_UI64, lld_ruleid); DBbegin(); DBexecute("%s", sql); DBcommit(); } clean: zbx_free(error); zbx_free(db_error); zbx_free(filter); zbx_free(discovery_key); zbx_free(sql); zbx_vector_ptr_clean(&lld_rows, (zbx_mem_free_func_t)lld_row_free); zbx_vector_ptr_destroy(&lld_rows); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: process_httptest * * * * Purpose: process single scenario of http test * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static void process_httptest(DB_HTTPTEST *httptest) { const char *__function_name = "process_httptest"; DB_RESULT result; DB_ROW row; DB_HTTPSTEP httpstep; char *err_str = NULL, *err_str_esc = NULL; int now, lastfailedstep; ZBX_HTTPSTAT stat; double speed_download = 0; int speed_download_num = 0; #ifdef HAVE_LIBCURL int err, opt; char auth[HTTPTEST_HTTP_USER_LEN_MAX + HTTPTEST_HTTP_PASSWORD_LEN_MAX]; CURL *easyhandle = NULL; #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s() httptestid:" ZBX_FS_UI64 " name:'%s'", __function_name, httptest->httptestid, httptest->name); lastfailedstep = 0; httptest->time = 0; now = time(NULL); DBexecute("update httptest" " set lastcheck=%d" " where httptestid=" ZBX_FS_UI64, now, httptest->httptestid); result = DBselect( "select httpstepid,no,name,url,timeout," "posts,required,status_codes" " from httpstep" " where httptestid=" ZBX_FS_UI64 " order by no", httptest->httptestid); #ifdef HAVE_LIBCURL if (NULL == (easyhandle = curl_easy_init())) { zabbix_log(LOG_LEVEL_ERR, "Web scenario [%s] error: could not init cURL library", httptest->name); err_str = zbx_strdup(err_str, "could not init cURL library"); goto clean; } if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_COOKIEFILE, "")) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_USERAGENT, httptest->agent)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_FOLLOWLOCATION, 1)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_WRITEFUNCTION, WRITEFUNCTION2)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HEADERFUNCTION, HEADERFUNCTION2)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYPEER, 0)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYHOST, 0)) || /* The pointed data are not copied by the library. As a consequence, the data */ /* must be preserved by the calling application until the transfer finishes. */ CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, httpstep.posts))) { zabbix_log(LOG_LEVEL_ERR, "Web scenario [%s] error: could not set cURL option [%d]: %s", httptest->name, opt, curl_easy_strerror(err)); err_str = zbx_strdup(err_str, curl_easy_strerror(err)); goto clean; } while (NULL == err_str && NULL != (row = DBfetch(result))) { /* NOTE: do not use break or return for this block! * process_step_data calling required! */ ZBX_STR2UINT64(httpstep.httpstepid, row[0]); httpstep.httptestid = httptest->httptestid; httpstep.no = atoi(row[1]); httpstep.name = row[2]; strscpy(httpstep.url, row[3]); httpstep.timeout = atoi(row[4]); strscpy(httpstep.posts, row[5]); strscpy(httpstep.required, row[6]); strscpy(httpstep.status_codes, row[7]); DBexecute("update httptest" " set curstep=%d," "curstate=%d" " where httptestid=" ZBX_FS_UI64, httpstep.no, HTTPTEST_STATE_BUSY, httptest->httptestid); memset(&stat, 0, sizeof(stat)); /* Substitute macros */ http_substitute_macros(httptest, httpstep.url, sizeof(httpstep.url)); http_substitute_macros(httptest, httpstep.posts, sizeof(httpstep.posts)); zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: use step [%s]", httpstep.name); if ('\0' != *httpstep.posts) { zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: use post [%s]", httpstep.posts); curl_easy_setopt(easyhandle, CURLOPT_POST, 1); } else curl_easy_setopt(easyhandle, CURLOPT_POST, 0); if (HTTPTEST_AUTH_NONE != httptest->authentication) { long curlauth = 0; zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: Setting HTTPAUTH [%d]", httptest->authentication); zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: Setting USERPWD for authentication"); switch (httptest->authentication) { case HTTPTEST_AUTH_BASIC: curlauth = CURLAUTH_BASIC; break; case HTTPTEST_AUTH_NTLM: curlauth = CURLAUTH_NTLM; break; default: THIS_SHOULD_NEVER_HAPPEN; break; } zbx_snprintf(auth, sizeof(auth), "%s:%s", httptest->http_user, httptest->http_password); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HTTPAUTH, curlauth)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_USERPWD, auth))) { zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: could not set cURL option [%d]: %s", httptest->name, httpstep.name, opt, curl_easy_strerror(err)); err_str = zbx_strdup(err_str, curl_easy_strerror(err)); } } if (NULL == err_str) { zabbix_log(LOG_LEVEL_DEBUG, "WEBMonitor: go to URL [%s]", httpstep.url); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_URL, httpstep.url)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_TIMEOUT, httpstep.timeout)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_CONNECTTIMEOUT, httpstep.timeout))) { zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: could not set cURL option [%d]: %s", httptest->name, httpstep.name, opt, curl_easy_strerror(err)); err_str = zbx_strdup(err_str, curl_easy_strerror(err)); } } if (NULL == err_str) { memset(&page, 0, sizeof(page)); if (CURLE_OK != (err = curl_easy_perform(easyhandle))) { zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error doing curl_easy_perform: %s", httptest->name, httpstep.name, curl_easy_strerror(err)); err_str = zbx_strdup(err_str, curl_easy_strerror(err)); } else { if ('\0' != httpstep.required[0] && NULL == zbx_regexp_match(page.data, httpstep.required, NULL)) { zabbix_log(LOG_LEVEL_DEBUG, "Page did not match [%s]", httpstep.required); err_str = zbx_strdup(err_str, "Page did not match"); } if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_RESPONSE_CODE, &stat.rspcode))) { zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error getting CURLINFO_RESPONSE_CODE: %s", httptest->name, httpstep.name, curl_easy_strerror(err)); err_str = (NULL == err_str ? zbx_strdup(err_str, curl_easy_strerror(err)) : err_str); } else if ('\0' != httpstep.status_codes[0] && FAIL == int_in_list(httpstep.status_codes, stat.rspcode)) { zabbix_log(LOG_LEVEL_DEBUG, "Status code did not match [%s]", httpstep.status_codes); err_str = (NULL == err_str ? zbx_strdup(err_str, "Status code did not match") : err_str); } if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_TOTAL_TIME, &stat.total_time))) { zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error getting CURLINFO_TOTAL_TIME: %s", httptest->name, httpstep.name, curl_easy_strerror(err)); err_str = (NULL == err_str ? zbx_strdup(err_str, curl_easy_strerror(err)) : err_str); } if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_SPEED_DOWNLOAD, &stat.speed_download))) { zabbix_log(LOG_LEVEL_ERR, "Web scenario step [%s:%s] error: error getting CURLINFO_SPEED_DOWNLOAD: %s", httptest->name, httpstep.name, curl_easy_strerror(err)); err_str = (NULL == err_str ? zbx_strdup(err_str, curl_easy_strerror(err)) : err_str); } else { speed_download += stat.speed_download; speed_download_num++; } } zbx_free(page.data); } if (NULL != err_str) lastfailedstep = httpstep.no; httptest->time += stat.total_time; process_step_data(httpstep.httpstepid, &stat); } clean: curl_easy_cleanup(easyhandle); #else err_str = zbx_strdup(err_str, "cURL library is required for Web monitoring support"); #endif /* HAVE_LIBCURL */ if (0 == lastfailedstep && NULL != err_str) { /* we are here either because cURL initialization failed before */ /* the first step or we have been compiled without cURL library */ lastfailedstep = 1; if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(httpstep.httpstepid, row[0]); memset(&stat, 0, sizeof(stat)); process_step_data(httpstep.httpstepid, &stat); } else THIS_SHOULD_NEVER_HAPPEN; } DBfree_result(result); err_str_esc = DBdyn_escape_string_len(err_str, HTTPTEST_ERROR_LEN); DBexecute("update httptest" " set curstep=0," "curstate=%d," "lastcheck=%d," "nextcheck=%d+delay," "lastfailedstep=%d," "time=" ZBX_FS_DBL "," "error='%s'" " where httptestid=" ZBX_FS_UI64, HTTPTEST_STATE_IDLE, now, now, lastfailedstep, httptest->time, err_str_esc, httptest->httptestid); zbx_free(err_str_esc); zbx_free(err_str); stat.test_total_time = httptest->time; stat.test_last_step = lastfailedstep; stat.speed_download = speed_download_num ? speed_download / speed_download_num : 0; process_test_data(httptest->httptestid, &stat); zabbix_log(LOG_LEVEL_DEBUG, "End of %s() total_time:" ZBX_FS_DBL, __function_name, httptest->time); }
/****************************************************************************** * * * Function: lld_gitems_get * * * * Purpose: retrieve graphs_items which are used by the graph prototype and * * by selected graphs * * * ******************************************************************************/ static void lld_gitems_get(zbx_uint64_t parent_graphid, zbx_vector_ptr_t *gitems_proto, zbx_vector_ptr_t *graphs) { const char *__function_name = "lld_gitems_get"; int i, index; zbx_lld_graph_t *graph; zbx_lld_gitem_t *gitem; zbx_uint64_t graphid; zbx_vector_uint64_t graphids; DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&graphids); zbx_vector_uint64_append(&graphids, parent_graphid); for (i = 0; i < graphs->values_num; i++) { graph = (zbx_lld_graph_t *)graphs->values[i]; zbx_vector_uint64_append(&graphids, graph->graphid); } zbx_vector_uint64_sort(&graphids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); sql = zbx_malloc(sql, sql_alloc); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select gitemid,graphid,itemid,drawtype,sortorder,color,yaxisside,calc_fnc,type" " from graphs_items" " where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "graphid", graphids.values, graphids.values_num); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { gitem = zbx_malloc(NULL, sizeof(zbx_lld_gitem_t)); ZBX_STR2UINT64(gitem->gitemid, row[0]); ZBX_STR2UINT64(graphid, row[1]); ZBX_STR2UINT64(gitem->itemid, row[2]); ZBX_STR2UCHAR(gitem->drawtype, row[3]); gitem->sortorder = atoi(row[4]); gitem->color = zbx_strdup(NULL, row[5]); ZBX_STR2UCHAR(gitem->yaxisside, row[6]); ZBX_STR2UCHAR(gitem->calc_fnc, row[7]); ZBX_STR2UCHAR(gitem->type, row[8]); gitem->flags = ZBX_FLAG_LLD_GITEM_UNSET; if (graphid == parent_graphid) { zbx_vector_ptr_append(gitems_proto, gitem); } else if (FAIL != (index = zbx_vector_ptr_bsearch(graphs, &graphid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { graph = (zbx_lld_graph_t *)graphs->values[index]; zbx_vector_ptr_append(&graph->gitems, gitem); } else { THIS_SHOULD_NEVER_HAPPEN; lld_gitem_free(gitem); } } DBfree_result(result); zbx_vector_ptr_sort(gitems_proto, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); for (i = 0; i < graphs->values_num; i++) { graph = (zbx_lld_graph_t *)graphs->values[i]; zbx_vector_ptr_sort(&graph->gitems, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); } zbx_vector_uint64_destroy(&graphids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void process_step_data(zbx_uint64_t httpstepid, zbx_httpstat_t *stat, zbx_timespec_t *ts) { const char *__function_name = "process_step_data"; DB_RESULT result; DB_ROW row; unsigned char types[3], states[3]; DC_ITEM items[3]; zbx_uint64_t itemids[3]; int lastclocks[3], errcodes[3]; size_t i, num = 0; AGENT_RESULT value; zabbix_log(LOG_LEVEL_DEBUG, "In %s() rspcode:%ld time:" ZBX_FS_DBL " speed:" ZBX_FS_DBL, __function_name, stat->rspcode, stat->total_time, stat->speed_download); result = DBselect("select type,itemid from httpstepitem where httpstepid=" ZBX_FS_UI64, httpstepid); while (NULL != (row = DBfetch(result))) { if (3 == num) { THIS_SHOULD_NEVER_HAPPEN; break; } if (ZBX_HTTPITEM_TYPE_RSPCODE != (types[num] = (unsigned char)atoi(row[0])) && ZBX_HTTPITEM_TYPE_TIME != types[num] && ZBX_HTTPITEM_TYPE_SPEED != types[num]) { THIS_SHOULD_NEVER_HAPPEN; continue; } ZBX_STR2UINT64(itemids[num], row[1]); num++; } DBfree_result(result); DCconfig_get_items_by_itemids(items, itemids, errcodes, num); for (i = 0; i < num; i++) { if (SUCCEED != errcodes[i]) continue; if (HOST_MAINTENANCE_STATUS_ON == items[i].host.maintenance_status && MAINTENANCE_TYPE_NODATA == items[i].host.maintenance_type) { continue; } init_result(&value); switch (types[i]) { case ZBX_HTTPITEM_TYPE_RSPCODE: SET_UI64_RESULT(&value, stat->rspcode); break; case ZBX_HTTPITEM_TYPE_TIME: SET_DBL_RESULT(&value, stat->total_time); break; case ZBX_HTTPITEM_TYPE_SPEED: SET_DBL_RESULT(&value, stat->speed_download); break; } items[i].state = ITEM_STATE_NORMAL; dc_add_history(items[i].itemid, items[i].value_type, 0, &value, ts, items[i].state, NULL); states[i] = items[i].state; lastclocks[i] = ts->sec; free_result(&value); } DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num); DCconfig_clean_items(items, errcodes, num); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_items_get * * * * Purpose: returns the list of items which are related to the graph * * prototype * * * * Parameters: gitems_proto - [IN] graph prototype's graphs_items * * ymin_itemid_proto - [IN] graph prototype's ymin_itemid * * ymax_itemid_proto - [IN] graph prototype's ymax_itemid * * items - [OUT] sorted list of items * * * ******************************************************************************/ static void lld_items_get(zbx_vector_ptr_t *gitems_proto, zbx_uint64_t ymin_itemid_proto, zbx_uint64_t ymax_itemid_proto, zbx_vector_ptr_t *items) { const char *__function_name = "lld_items_get"; DB_RESULT result; DB_ROW row; zbx_lld_gitem_t *gitem; zbx_lld_item_t *item; zbx_vector_uint64_t itemids; int i; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&itemids); for (i = 0; i < gitems_proto->values_num; i++) { gitem = (zbx_lld_gitem_t *)gitems_proto->values[i]; zbx_vector_uint64_append(&itemids, gitem->itemid); } if (0 != ymin_itemid_proto) zbx_vector_uint64_append(&itemids, ymin_itemid_proto); if (0 != ymax_itemid_proto) zbx_vector_uint64_append(&itemids, ymax_itemid_proto); if (0 != itemids.values_num) { char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); sql = zbx_malloc(sql, sql_alloc); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,flags" " from items" " where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { item = zbx_malloc(NULL, sizeof(zbx_lld_item_t)); ZBX_STR2UINT64(item->itemid, row[0]); ZBX_STR2UCHAR(item->flags, row[1]); zbx_vector_ptr_append(items, item); } DBfree_result(result); zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); } zbx_vector_uint64_destroy(&itemids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: process_httptest * * * * Purpose: process single scenario of http test * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static void process_httptest(DC_HOST *host, zbx_httptest_t *httptest) { const char *__function_name = "process_httptest"; DB_RESULT result; DB_ROW row; DB_HTTPSTEP httpstep; char *err_str = NULL; int lastfailedstep; zbx_timespec_t ts; zbx_httpstat_t stat; double speed_download = 0; int speed_download_num = 0; #ifdef HAVE_LIBCURL int err; char auth[HTTPTEST_HTTP_USER_LEN_MAX + HTTPTEST_HTTP_PASSWORD_LEN_MAX]; CURL *easyhandle = NULL; #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s() httptestid:" ZBX_FS_UI64 " name:'%s'", __function_name, httptest->httptest.httptestid, httptest->httptest.name); lastfailedstep = 0; result = DBselect( "select httpstepid,no,name,url,timeout,posts,required,status_codes,variables" " from httpstep" " where httptestid=" ZBX_FS_UI64 " order by no", httptest->httptest.httptestid); #ifdef HAVE_LIBCURL if (NULL == (easyhandle = curl_easy_init())) { err_str = zbx_strdup(err_str, "cannot initialize cURL library"); goto clean; } if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_PROXY, httptest->httptest.http_proxy)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_COOKIEFILE, "")) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, httptest->httptest.agent)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 1L)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, WRITEFUNCTION2)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, HEADERFUNCTION2)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, 0L)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, 0L))) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); goto clean; } while (NULL != (row = DBfetch(result))) { /* NOTE: do not break or return from this block! */ /* process_step_data() call is required! */ ZBX_STR2UINT64(httpstep.httpstepid, row[0]); httpstep.httptestid = httptest->httptest.httptestid; httpstep.no = atoi(row[1]); httpstep.name = row[2]; httpstep.url = zbx_strdup(NULL, row[3]); substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, host, NULL, &httpstep.url, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0); httpstep.timeout = atoi(row[4]); httpstep.posts = zbx_strdup(NULL, row[5]); substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, host, NULL, &httpstep.posts, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0); httpstep.required = zbx_strdup(NULL, row[6]); substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, host, NULL, &httpstep.required, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0); httpstep.status_codes = zbx_strdup(NULL, row[7]); substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL, &httpstep.status_codes, MACRO_TYPE_COMMON, NULL, 0); httpstep.variables = row[8]; memset(&stat, 0, sizeof(stat)); http_substitute_variables(httptest, &httpstep.url); http_substitute_variables(httptest, &httpstep.posts); zabbix_log(LOG_LEVEL_DEBUG, "%s() use step \"%s\"", __function_name, httpstep.name); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, httpstep.posts))) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); goto httpstep_error; } if ('\0' != *httpstep.posts) zabbix_log(LOG_LEVEL_DEBUG, "%s() use post \"%s\"", __function_name, httpstep.posts); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_POST, '\0' != *httpstep.posts ? 1L : 0L))) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); goto httpstep_error; } if (HTTPTEST_AUTH_NONE != httptest->httptest.authentication) { long curlauth = 0; zabbix_log(LOG_LEVEL_DEBUG, "%s() setting HTTPAUTH [%d]", __function_name, httptest->httptest.authentication); zabbix_log(LOG_LEVEL_DEBUG, "%s() setting USERPWD for authentication", __function_name); switch (httptest->httptest.authentication) { case HTTPTEST_AUTH_BASIC: curlauth = CURLAUTH_BASIC; break; case HTTPTEST_AUTH_NTLM: curlauth = CURLAUTH_NTLM; break; default: THIS_SHOULD_NEVER_HAPPEN; break; } zbx_snprintf(auth, sizeof(auth), "%s:%s", httptest->httptest.http_user, httptest->httptest.http_password); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, curlauth)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_USERPWD, auth))) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); goto httpstep_error; } } zabbix_log(LOG_LEVEL_DEBUG, "%s() go to URL \"%s\"", __function_name, httpstep.url); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_TIMEOUT, (long)httpstep.timeout)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_URL, httpstep.url))) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); goto httpstep_error; } /* try to retrieve page several times depending on number of retries */ do { memset(&page, 0, sizeof(page)); if (CURLE_OK == (err = curl_easy_perform(easyhandle))) break; } while (0 != --httptest->httptest.retries); if (CURLE_OK == err) { char *var_err_str = NULL; /* first get the data that is needed even if step fails */ if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_RESPONSE_CODE, &stat.rspcode))) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); } else if ('\0' != *httpstep.status_codes && FAIL == int_in_list(httpstep.status_codes, stat.rspcode)) { err_str = zbx_strdup(err_str, "status code did not match"); } if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_TOTAL_TIME, &stat.total_time)) && NULL == err_str) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); } if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_SPEED_DOWNLOAD, &stat.speed_download)) && NULL == err_str) { err_str = zbx_strdup(err_str, curl_easy_strerror(err)); } else { speed_download += stat.speed_download; speed_download_num++; } /* required pattern */ if (NULL == err_str && '\0' != *httpstep.required && NULL == zbx_regexp_match(page.data, httpstep.required, NULL)) { err_str = zbx_strdup(err_str, "required pattern not found"); } /* variables defined in scenario */ if (NULL == err_str && FAIL == http_process_variables(httptest, httptest->httptest.variables, page.data, &var_err_str)) { char *variables; variables = string_replace(httptest->httptest.variables, "\r\n", " "); err_str = zbx_dsprintf(err_str, "error in scenario variables \"%s\": %s", variables, var_err_str); zbx_free(variables); } /* variables defined in a step */ if (NULL == err_str && FAIL == http_process_variables(httptest, httpstep.variables, page.data, &var_err_str)) { char *variables; variables = string_replace(httpstep.variables, "\r\n", " "); err_str = zbx_dsprintf(err_str, "error in step variables \"%s\": %s", variables, var_err_str); zbx_free(variables); } zbx_free(var_err_str); } else err_str = zbx_strdup(err_str, curl_easy_strerror(err)); zbx_free(page.data); httpstep_error: zbx_free(httpstep.status_codes); zbx_free(httpstep.required); zbx_free(httpstep.posts); zbx_free(httpstep.url); zbx_timespec(&ts); process_step_data(httpstep.httpstepid, &stat, &ts); if (NULL != err_str) { lastfailedstep = httpstep.no; break; } } clean: curl_easy_cleanup(easyhandle); #else err_str = zbx_strdup(err_str, "cURL library is required for Web monitoring support"); #endif /* HAVE_LIBCURL */ zbx_timespec(&ts); if (NULL != err_str) { if (0 == lastfailedstep) { /* we are here either because cURL initialization failed */ /* or we have been compiled without cURL library */ lastfailedstep = 1; if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(httpstep.httpstepid, row[0]); httpstep.name = row[2]; memset(&stat, 0, sizeof(stat)); process_step_data(httpstep.httpstepid, &stat, &ts); } else THIS_SHOULD_NEVER_HAPPEN; } zabbix_log(LOG_LEVEL_WARNING, "cannot process step \"%s\" of web scenario \"%s\" on host \"%s\": %s", httpstep.name, httptest->httptest.name, host->name, err_str); } DBfree_result(result); DBexecute("update httptest set nextcheck=%d+delay where httptestid=" ZBX_FS_UI64, ts.sec, httptest->httptest.httptestid); if (0 != speed_download_num) speed_download /= speed_download_num; process_test_data(httptest->httptest.httptestid, lastfailedstep, speed_download, err_str, &ts); zbx_free(err_str); dc_flush_history(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void execute_operations(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action) { DB_RESULT result; DB_ROW row; DB_OPERATION operation; int esc_period = 0, operations = 0; ZBX_USER_MSG *user_msg = NULL, *p; char *shortdata, *longdata; if (0 == action->esc_period) { result = DBselect("select operationid,operationtype,object,objectid,default_msg,shortdata,longdata" ",esc_period,evaltype from operations where actionid=" ZBX_FS_UI64 " and operationtype in (%d,%d)", action->actionid, OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND); } else { escalation->esc_step++; result = DBselect("select operationid,operationtype,object,objectid,default_msg,shortdata,longdata" ",esc_period,evaltype from operations where actionid=" ZBX_FS_UI64 " and operationtype in (%d,%d)" " and esc_step_from<=%d and (esc_step_to=0 or esc_step_to>=%d)", action->actionid, OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND, escalation->esc_step, escalation->esc_step); } while (NULL != (row = DBfetch(result))) { memset(&operation, 0, sizeof(operation)); ZBX_STR2UINT64(operation.operationid, row[0]); operation.actionid = action->actionid; operation.operationtype = atoi(row[1]); operation.object = atoi(row[2]); ZBX_STR2UINT64(operation.objectid, row[3]); operation.default_msg = atoi(row[4]); operation.shortdata = strdup(row[5]); operation.longdata = strdup(row[6]); operation.esc_period = atoi(row[7]); operation.evaltype = atoi(row[8]); if (SUCCEED == check_operation_conditions(event, &operation)) { zabbix_log(LOG_LEVEL_DEBUG, "Conditions match our event. Execute operation."); substitute_macros(event, action, NULL, &operation.shortdata); substitute_macros(event, action, NULL, &operation.longdata); if (0 == esc_period || esc_period > operation.esc_period) esc_period = operation.esc_period; switch (operation.operationtype) { case OPERATION_TYPE_MESSAGE: if (0 == operation.default_msg) { shortdata = operation.shortdata; longdata = operation.longdata; } else { shortdata = action->shortdata; longdata = action->longdata; } add_object_msg(event->source, escalation->triggerid, &operation, &user_msg, shortdata, longdata); break; case OPERATION_TYPE_COMMAND: add_command_alert(escalation, event, action, operation.longdata); break; default: break; } } else zabbix_log(LOG_LEVEL_DEBUG, "Conditions do not match our event. Do not execute operation."); zbx_free(operation.shortdata); zbx_free(operation.longdata); operations = 1; } DBfree_result(result); while (NULL != user_msg) { p = user_msg; user_msg = user_msg->next; add_message_alert(escalation, event, action, p->userid, p->mediatypeid, p->subject, p->message); zbx_free(p->subject); zbx_free(p->message); zbx_free(p); } if (0 == action->esc_period) { escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED; } else { if (0 == operations) { result = DBselect("select operationid from operations where actionid=" ZBX_FS_UI64 " and esc_step_from>%d", action->actionid, escalation->esc_step); if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0])) operations = 1; DBfree_result(result); } if (1 == operations) { esc_period = (0 != esc_period) ? esc_period : action->esc_period; escalation->nextcheck = time(NULL) + esc_period; } else escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED; } }
/****************************************************************************** * * * Function: process_httptests * * * * Purpose: process httptests * * * * Parameters: now - current timestamp * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: always SUCCEED * * * ******************************************************************************/ int process_httptests(int httppoller_num, int now) { const char *__function_name = "process_httptests"; DB_RESULT result; DB_ROW row; zbx_httptest_t httptest; DC_HOST host; int httptests_count = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); /* create macro cache to use in http tests */ zbx_vector_ptr_pair_create(&httptest.macros); result = DBselect( "select h.hostid,h.host,h.name,t.httptestid,t.name,t.variables,t.agent," "t.authentication,t.http_user,t.http_password,t.http_proxy,t.retries" " from httptest t,hosts h" " where t.hostid=h.hostid" " and t.nextcheck<=%d" " and " ZBX_SQL_MOD(t.httptestid,%d) "=%d" " and t.status=%d" " and h.proxy_hostid is null" " and h.status=%d" " and (h.maintenance_status=%d or h.maintenance_type=%d)" ZBX_SQL_NODE, now, CONFIG_HTTPPOLLER_FORKS, httppoller_num - 1, HTTPTEST_STATUS_MONITORED, HOST_STATUS_MONITORED, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBand_node_local("t.httptestid")); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(host.hostid, row[0]); strscpy(host.host, row[1]); strscpy(host.name, row[2]); ZBX_STR2UINT64(httptest.httptest.httptestid, row[3]); httptest.httptest.name = row[4]; httptest.httptest.variables = zbx_strdup(NULL, row[5]); substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, &host, NULL, &httptest.httptest.variables, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0); httptest.httptest.agent = zbx_strdup(NULL, row[6]); substitute_simple_macros(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, &httptest.httptest.agent, MACRO_TYPE_COMMON, NULL, 0); if (HTTPTEST_AUTH_NONE != (httptest.httptest.authentication = atoi(row[7]))) { httptest.httptest.http_user = zbx_strdup(NULL, row[8]); substitute_simple_macros(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, &httptest.httptest.http_user, MACRO_TYPE_COMMON, NULL, 0); httptest.httptest.http_password = zbx_strdup(NULL, row[9]); substitute_simple_macros(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, &httptest.httptest.http_password, MACRO_TYPE_COMMON, NULL, 0); } httptest.httptest.http_proxy = zbx_strdup(NULL, row[10]); substitute_simple_macros(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, &httptest.httptest.http_proxy, MACRO_TYPE_COMMON, NULL, 0); httptest.httptest.retries = atoi(row[11]); /* add httptest varriables to the current test macro cache */ http_process_variables(&httptest, httptest.httptest.variables, NULL, NULL); process_httptest(&host, &httptest); zbx_free(httptest.httptest.http_proxy); if (HTTPTEST_AUTH_NONE != httptest.httptest.authentication) { zbx_free(httptest.httptest.http_password); zbx_free(httptest.httptest.http_user); } zbx_free(httptest.httptest.agent); zbx_free(httptest.httptest.variables); /* clear the macro cache used in this http test */ httptest_remove_macros(&httptest); httptests_count++; /* performance metric */ } /* destroy the macro cache used in http tests */ zbx_vector_ptr_pair_destroy(&httptest.macros); DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return httptests_count; }
/****************************************************************************** * * * 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); } }
/****************************************************************************** * * * Function: register_service * * * * Purpose: register service if one does not exist * * * * Parameters: host ip address * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static void register_service(DB_DSERVICE *service,DB_DRULE *rule,DB_DCHECK *check,zbx_uint64_t dhostid,char *ip,int port) { DB_RESULT result; DB_ROW row; char value_esc[MAX_STRING_LEN]; char key_esc[MAX_STRING_LEN]; assert(service); assert(rule); assert(check); assert(ip); zabbix_log(LOG_LEVEL_DEBUG, "In register_service(ip:%s,port:%d)", ip, port); DBescape_string(check->key_, key_esc, sizeof(key_esc)-1); result = DBselect("select dserviceid,dhostid,type,port,status,lastup,lastdown,value,key_ from dservices where dhostid=" ZBX_FS_UI64 " and type=%d and port=%d and key_='%s'", dhostid, check->type, port, key_esc); row=DBfetch(result); if(!row || DBis_null(row[0])==SUCCEED) { /* Add host only if service is up */ if(check->status == DOBJECT_STATUS_UP) { zabbix_log(LOG_LEVEL_DEBUG, "New service discovered on port %d", port); service->dserviceid = DBget_maxid("dservices","dserviceid"); service->dhostid = dhostid; service->type = check->type; service->port = port; service->status = DOBJECT_STATUS_UP; service->lastup = 0; service->lastdown = 0; strscpy(service->value, check->value); strscpy(service->key_, check->key_); DBescape_string(service->value, value_esc, sizeof(value_esc)-1); DBescape_string(service->key_, key_esc, sizeof(key_esc)-1); DBexecute("insert into dservices (dhostid,dserviceid,type,port,status,value,key_) values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d,%d,'%s','%s')", service->dhostid, service->dserviceid, check->type, service->port, service->status, value_esc, key_esc); } } else { zabbix_log(LOG_LEVEL_DEBUG, "Service is already in database"); ZBX_STR2UINT64(service->dserviceid, row[0]); ZBX_STR2UINT64(service->dhostid, row[1]); service->type = atoi(row[2]); service->port = atoi(row[3]); service->status = atoi(row[4]); service->lastup = atoi(row[5]); service->lastdown = atoi(row[6]); strscpy(service->value,row[7]); strscpy(service->key_,row[8]); } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End register_service()"); }
static void run_remote_command(char* host_name, char* command) { int ret = 9; AGENT_RESULT agent_result; DC_ITEM item; DB_RESULT result; DB_ROW row; char *p, *host_esc, *param; #ifdef HAVE_OPENIPMI int val; char error[MAX_STRING_LEN]; #endif assert(host_name); assert(command); zabbix_log(LOG_LEVEL_DEBUG, "In run_remote_command(hostname:%s,command:%s)", host_name, command); host_esc = DBdyn_escape_string(host_name); result = DBselect( "select hostid,host,useip,ip,dns,port,useipmi,ipmi_ip,ipmi_port,ipmi_authtype," "ipmi_privilege,ipmi_username,ipmi_password" " from hosts" " where status in (%d)" " and host='%s'" DB_NODE, HOST_STATUS_MONITORED, host_esc, DBnode_local("hostid")); zbx_free(host_esc); if (NULL != (row = DBfetch(result))) { memset(&item, 0, sizeof(item)); ZBX_STR2UINT64(item.host.hostid, row[0]); zbx_strlcpy(item.host.host, row[1], sizeof(item.host.host)); item.host.useip = (unsigned char)atoi(row[2]); zbx_strlcpy(item.host.ip, row[3], sizeof(item.host.ip)); zbx_strlcpy(item.host.dns, row[4], sizeof(item.host.dns)); item.host.port = (unsigned short)atoi(row[5]); p = command; while (*p == ' ' && *p != '\0') p++; #ifdef HAVE_OPENIPMI if (0 == strncmp(p, "IPMI", 4)) { if (1 == atoi(row[6])) { zbx_strlcpy(item.host.ipmi_ip_orig, row[7], sizeof(item.host.ipmi_ip)); item.host.ipmi_port = (unsigned short)atoi(row[8]); item.host.ipmi_authtype = atoi(row[9]); item.host.ipmi_privilege = atoi(row[10]); zbx_strlcpy(item.host.ipmi_username, row[11], sizeof(item.host.ipmi_username)); zbx_strlcpy(item.host.ipmi_password, row[12], sizeof(item.host.ipmi_password)); } if (SUCCEED == (ret = parse_ipmi_command(p, item.ipmi_sensor, &val))) { item.key = item.ipmi_sensor; ret = set_ipmi_control_value(&item, val, error, sizeof(error)); } } else { #endif param = zbx_dyn_escape_string(p, "\""); item.key = zbx_dsprintf(NULL, "system.run[\"%s\",\"nowait\"]", param); zbx_free(param); init_result(&agent_result); alarm(CONFIG_TIMEOUT); ret = get_value_agent(&item, &agent_result); alarm(0); free_result(&agent_result); zbx_free(item.key); #ifdef HAVE_OPENIPMI } #endif } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End run_remote_command(result:%d)", ret); }
/****************************************************************************** * * * Function: process_rule * * * * Purpose: process single discovery rule * * * * Parameters: * * * * Return value: * * * * Author: Eugene Grigorjev * * * * Comments: * * * ******************************************************************************/ static void process_rule(DB_DRULE *rule) { DB_RESULT result; DB_ROW row; DB_DCHECK check; char ip[MAX_STRING_LEN], prefix[MAX_STRING_LEN]; unsigned int j[9], i; int first, last, ipv6; char *curr_range = NULL, *next_range = NULL, *dash = NULL; #if defined(HAVE_IPV6) char *colon; #endif assert(rule); zabbix_log(LOG_LEVEL_DEBUG, "In process_rule() [name:%s] [range:%s]", rule->name, rule->iprange); for ( curr_range = rule->iprange; curr_range; curr_range = next_range ) { /* split by ',' */ if ( NULL != (next_range = strchr(curr_range, ',')) ) { next_range[0] = '\0'; } if ( NULL != (dash = strchr(curr_range, '-')) ) { dash[0] = '\0'; } first = last = -1; #if defined(HAVE_IPV6) if ( SUCCEED == expand_ipv6(curr_range, ip, sizeof(ip)) ) { ipv6 = 1; if( sscanf(ip, "%x:%x:%x:%x:%x:%x:%x:%x", &j[0], &j[1], &j[2], &j[3], &j[4], &j[5], &j[6], &j[7]) == 8 ) { first = j[7]; zbx_strlcpy( prefix, curr_range, sizeof(prefix) ); if( NULL != (colon = strrchr(prefix, ':')) ) { ( colon + 1 )[0] = '\0'; } } if( dash != NULL ) { if( sscanf(dash + 1, "%x", &j[8]) == 1 ) { last = j[8]; } } else { last = first; } } else { #endif /* HAVE_IPV6 */ ipv6 = 0; if( sscanf(curr_range, "%d.%d.%d.%d", &j[0], &j[1], &j[2], &j[3]) == 4 ) { first = j[3]; } if( dash != NULL ) { if( sscanf(dash + 1, "%d", &j[4]) == 1 ) { last = j[4]; } } else { last = first; } #if defined(HAVE_IPV6) } #endif /* HAVE_IPV6 */ if( dash ) { dash[0] = '-'; dash = NULL; } if ( next_range ) { next_range[0] = ','; next_range ++; } if( first < 0 || last < 0 ) { zabbix_log(LOG_LEVEL_WARNING, "Discovery: Wrong format of IP range [%s]", rule->iprange); continue; } for ( i = first; i <= last; i++ ) { switch( ipv6 ) { case 0 : zbx_snprintf(ip, sizeof(ip), "%d.%d.%d.%d", j[0], j[1], j[2], i); break; case 1 : zbx_snprintf(ip, sizeof(ip), "%s%x", prefix, i); break; } zabbix_log(LOG_LEVEL_DEBUG, "Discovery: process_rule() [IP:%s]", ip); result = DBselect("select dcheckid,druleid,type,key_,snmp_community,ports from dchecks where druleid=" ZBX_FS_UI64, rule->druleid); while((row=DBfetch(result))) { memset(&check, 0, sizeof(DB_RESULT)); ZBX_STR2UINT64(check.dcheckid,row[0]); ZBX_STR2UINT64(check.druleid,row[1]); check.type = atoi(row[2]); check.key_ = row[3]; check.snmp_community = row[4]; check.ports = row[5]; process_check(rule, &check, ip); } DBfree_result(result); add_host_event(ip); } } zabbix_log( LOG_LEVEL_DEBUG, "End process_rule()"); }
static void process_escalations(int now) { const char *__function_name = "process_escalations"; DB_RESULT result; DB_ROW row; DB_ESCALATION escalation, last_escalation; zbx_vector_uint64_t escalationids; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&escalationids); sql = zbx_malloc(sql, sql_alloc); result = DBselect( "select escalationid,actionid,triggerid,eventid,r_eventid,esc_step,status,nextcheck" " from escalations" " where 1=1" DB_NODE " order by actionid,triggerid,escalationid", DBnode_local("escalationid")); memset(&escalation, 0, sizeof(escalation)); do { memset(&last_escalation, 0, sizeof(last_escalation)); if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(last_escalation.escalationid, row[0]); ZBX_STR2UINT64(last_escalation.actionid, row[1]); ZBX_DBROW2UINT64(last_escalation.triggerid, row[2]); ZBX_DBROW2UINT64(last_escalation.eventid, row[3]); ZBX_DBROW2UINT64(last_escalation.r_eventid, row[4]); last_escalation.esc_step = atoi(row[5]); last_escalation.status = atoi(row[6]); last_escalation.nextcheck = atoi(row[7]); /* just delete on the next cycle */ if (0 != last_escalation.r_eventid) last_escalation.status = ESCALATION_STATUS_COMPLETED; } if (0 != escalation.escalationid) { unsigned char esc_superseded = 0; if (ESCALATION_STATUS_COMPLETED == escalation.status) { /* delete a recovery record and skip all processing */ zbx_vector_uint64_append(&escalationids, escalation.escalationid); goto next; } if (0 != last_escalation.escalationid) { esc_superseded = (escalation.actionid == last_escalation.actionid && escalation.triggerid == last_escalation.triggerid); if (1 == esc_superseded) { if (0 != last_escalation.r_eventid) { /* recover this escalation */ escalation.r_eventid = last_escalation.r_eventid; escalation.status = ESCALATION_STATUS_ACTIVE; } else if (escalation.nextcheck > now || ESCALATION_STATUS_SLEEP == escalation.status) { zbx_vector_uint64_append(&escalationids, escalation.escalationid); goto next; } } } if (ESCALATION_STATUS_ACTIVE != escalation.status || (escalation.nextcheck > now && 0 == escalation.r_eventid)) { goto next; } DBbegin(); if (escalation.nextcheck <= now) execute_escalation(&escalation); /* execute recovery */ if (ESCALATION_STATUS_COMPLETED != escalation.status && 0 != escalation.r_eventid) { escalation.status = ESCALATION_STATUS_RECOVERY; execute_escalation(&escalation); } else if (1 == esc_superseded) escalation.status = ESCALATION_STATUS_COMPLETED; sql_offset = 0; if (ESCALATION_STATUS_COMPLETED != escalation.status) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update escalations set status=%d", escalation.status); if (ESCALATION_STATUS_ACTIVE == escalation.status) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ",esc_step=%d,nextcheck=%d", escalation.esc_step, escalation.nextcheck); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where escalationid=" ZBX_FS_UI64, escalation.escalationid); } else { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from escalations where escalationid=" ZBX_FS_UI64, escalation.escalationid); } DBexecute("%s", sql); DBcommit(); } next: if (NULL != row) memcpy(&escalation, &last_escalation, sizeof(escalation)); } while (NULL != row); DBfree_result(result); zbx_free(sql); /* delete completed escalations */ if (0 != escalationids.values_num) { zbx_vector_uint64_sort(&escalationids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); DBbegin(); DBexecute_multiple_query("delete from escalations where", "escalationid", &escalationids); DBcommit(); } zbx_vector_uint64_destroy(&escalationids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_update_graphs * * * * Purpose: add or update graphs for discovery item * * * * Parameters: hostid - [IN] host identificator from database * * agent - [IN] discovery item identificator from database * * jp_data - [IN] received data * * * * Author: Alexander Vladishev * * * ******************************************************************************/ void lld_update_graphs(zbx_uint64_t hostid, zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *lld_rows, char **error) { const char *__function_name = "lld_update_graphs"; DB_RESULT result; DB_ROW row; zbx_vector_ptr_t graphs; zbx_vector_ptr_t gitems_proto; zbx_vector_ptr_t items; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&graphs); /* list of graphs which were created or will be created or */ /* updated by the graph prototype */ zbx_vector_ptr_create(&gitems_proto); /* list of graphs_items which are used by the graph prototype */ zbx_vector_ptr_create(&items); /* list of items which are related to the graph prototype */ result = DBselect( "select distinct g.graphid,g.name,g.width,g.height,g.yaxismin,g.yaxismax,g.show_work_period," "g.show_triggers,g.graphtype,g.show_legend,g.show_3d,g.percent_left,g.percent_right," "g.ymin_type,g.ymin_itemid,g.ymax_type,g.ymax_itemid" " from graphs g,graphs_items gi,items i,item_discovery id" " where g.graphid=gi.graphid" " and gi.itemid=i.itemid" " and i.itemid=id.itemid" " and id.parent_itemid=" ZBX_FS_UI64, lld_ruleid); while (NULL != (row = DBfetch(result))) { zbx_uint64_t parent_graphid, ymin_itemid_proto, ymax_itemid_proto; const char *name_proto; int width, height; double yaxismin, yaxismax, percent_left, percent_right; unsigned char show_work_period, show_triggers, graphtype, show_legend, show_3d, ymin_type, ymax_type; ZBX_STR2UINT64(parent_graphid, row[0]); name_proto = row[1]; width = atoi(row[2]); height = atoi(row[3]); yaxismin = atof(row[4]); yaxismax = atof(row[5]); ZBX_STR2UCHAR(show_work_period, row[6]); ZBX_STR2UCHAR(show_triggers, row[7]); ZBX_STR2UCHAR(graphtype, row[8]); ZBX_STR2UCHAR(show_legend, row[9]); ZBX_STR2UCHAR(show_3d, row[10]); percent_left = atof(row[11]); percent_right = atof(row[12]); ZBX_STR2UCHAR(ymin_type, row[13]); ZBX_DBROW2UINT64(ymin_itemid_proto, row[14]); ZBX_STR2UCHAR(ymax_type, row[15]); ZBX_DBROW2UINT64(ymax_itemid_proto, row[16]); lld_graphs_get(parent_graphid, &graphs, width, height, yaxismin, yaxismax, show_work_period, show_triggers, graphtype, show_legend, show_3d, percent_left, percent_right, ymin_type, ymax_type); lld_gitems_get(parent_graphid, &gitems_proto, &graphs); lld_items_get(&gitems_proto, ymin_itemid_proto, ymax_itemid_proto, &items); /* making graphs */ lld_graphs_make(&gitems_proto, &graphs, &items, name_proto, ymin_itemid_proto, ymax_itemid_proto, lld_rows); lld_graphs_validate(hostid, &graphs, error); lld_graphs_save(parent_graphid, &graphs, width, height, yaxismin, yaxismax, show_work_period, show_triggers, graphtype, show_legend, show_3d, percent_left, percent_right, ymin_type, ymax_type); lld_items_free(&items); lld_gitems_free(&gitems_proto); lld_graphs_free(&graphs); } DBfree_result(result); zbx_vector_ptr_destroy(&items); zbx_vector_ptr_destroy(&gitems_proto); zbx_vector_ptr_destroy(&graphs); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void execute_commands(DB_EVENT *event, zbx_uint64_t actionid, zbx_uint64_t operationid, int esc_step) { const char *__function_name = "execute_commands"; DB_RESULT result; DB_ROW row; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect( "select distinct h.hostid,h.host,o.type,o.scriptid,o.execute_on,o.port" ",o.authtype,o.username,o.password,o.publickey,o.privatekey,o.command" #ifdef HAVE_OPENIPMI ",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password" #endif " from opcommand o,opcommand_grp og,hosts_groups hg,hosts h" " where o.operationid=og.operationid" " and og.groupid=hg.groupid" " and hg.hostid=h.hostid" " and o.operationid=" ZBX_FS_UI64 " and h.status=%d" " union " "select distinct h.hostid,h.host,o.type,o.scriptid,o.execute_on,o.port" ",o.authtype,o.username,o.password,o.publickey,o.privatekey,o.command" #ifdef HAVE_OPENIPMI ",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password" #endif " from opcommand o,opcommand_hst oh,hosts h" " where o.operationid=oh.operationid" " and oh.hostid=h.hostid" " and o.operationid=" ZBX_FS_UI64 " and h.status=%d" " union " "select distinct 0,null,o.type,o.scriptid,o.execute_on,o.port" ",o.authtype,o.username,o.password,o.publickey,o.privatekey,o.command" #ifdef HAVE_OPENIPMI ",0,2,null,null" #endif " from opcommand o,opcommand_hst oh" " where o.operationid=oh.operationid" " and o.operationid=" ZBX_FS_UI64 " and oh.hostid is null", operationid, HOST_STATUS_MONITORED, operationid, HOST_STATUS_MONITORED, operationid); while (NULL != (row = DBfetch(result))) { int rc = SUCCEED; char error[ALERT_ERROR_LEN_MAX]; DC_HOST host; zbx_script_t script; zbx_alert_status_t status; *error = '\0'; memset(&host, 0, sizeof(host)); zbx_script_init(&script); ZBX_STR2UINT64(host.hostid, row[0]); if (0 != host.hostid) { strscpy(host.host, row[1]); #ifdef HAVE_OPENIPMI host.ipmi_authtype = (signed char)atoi(row[12]); host.ipmi_privilege = (unsigned char)atoi(row[13]); strscpy(host.ipmi_username, row[14]); strscpy(host.ipmi_password, row[15]); #endif } else rc = get_dynamic_hostid(event, &host, error, sizeof(error)); script.type = (unsigned char)atoi(row[2]); if (ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT != script.type) { script.command = zbx_strdup(script.command, row[11]); substitute_simple_macros(event, NULL, NULL, NULL, NULL, NULL, &script.command, MACRO_TYPE_MESSAGE, NULL, 0); } if (SUCCEED == rc) { switch (script.type) { case ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT: script.execute_on = (unsigned char)atoi(row[4]); break; case ZBX_SCRIPT_TYPE_SSH: script.authtype = (unsigned char)atoi(row[6]); script.publickey = zbx_strdup(script.publickey, row[9]); script.privatekey = zbx_strdup(script.privatekey, row[10]); /* break; is not missing here */ case ZBX_SCRIPT_TYPE_TELNET: script.port = zbx_strdup(script.port, row[5]); script.username = zbx_strdup(script.username, row[7]); script.password = zbx_strdup(script.password, row[8]); break; case ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT: ZBX_DBROW2UINT64(script.scriptid, row[3]); break; } rc = zbx_execute_script(&host, &script, NULL, error, sizeof(error)); } status = (SUCCEED != rc ? ALERT_STATUS_FAILED : ALERT_STATUS_SENT); add_command_alert(&host, event->eventid, actionid, esc_step, script.command, status, error); zbx_script_clean(&script); } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_graphs_get * * * * Purpose: retrieve graphs which were created by the specified graph * * prototype * * * * Parameters: parent_graphid - [IN] graph prototype identificator * * graphs - [OUT] sorted list of graphs * * * ******************************************************************************/ static void lld_graphs_get(zbx_uint64_t parent_graphid, zbx_vector_ptr_t *graphs, int width, int height, double yaxismin, double yaxismax, unsigned char show_work_period, unsigned char show_triggers, unsigned char graphtype, unsigned char show_legend, unsigned char show_3d, double percent_left, double percent_right, unsigned char ymin_type, unsigned char ymax_type) { const char *__function_name = "lld_graphs_get"; DB_RESULT result; DB_ROW row; zbx_lld_graph_t *graph; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect( "select g.graphid,g.name,g.width,g.height,g.yaxismin,g.yaxismax,g.show_work_period," "g.show_triggers,g.graphtype,g.show_legend,g.show_3d,g.percent_left,g.percent_right," "g.ymin_type,g.ymin_itemid,g.ymax_type,g.ymax_itemid" " from graphs g,graph_discovery gd" " where g.graphid=gd.graphid" " and gd.parent_graphid=" ZBX_FS_UI64, parent_graphid); while (NULL != (row = DBfetch(result))) { graph = zbx_malloc(NULL, sizeof(zbx_lld_graph_t)); ZBX_STR2UINT64(graph->graphid, row[0]); graph->name = zbx_strdup(NULL, row[1]); graph->name_orig = NULL; graph->flags = ZBX_FLAG_LLD_GRAPH_UNSET; if (atoi(row[2]) != width) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_WIDTH; if (atoi(row[3]) != height) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_HEIGHT; if (atof(row[4]) != yaxismin) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMIN; if (atof(row[5]) != yaxismax) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMAX; if ((unsigned char)atoi(row[6]) != show_work_period) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_WORK_PERIOD; if ((unsigned char)atoi(row[7]) != show_triggers) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_TRIGGERS; if ((unsigned char)atoi(row[8]) != graphtype) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_GRAPHTYPE; if ((unsigned char)atoi(row[9]) != show_legend) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_LEGEND; if ((unsigned char)atoi(row[10]) != show_3d) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_3D; if (atof(row[11]) != percent_left) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_LEFT; if (atof(row[12]) != percent_right) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_RIGHT; if ((unsigned char)atoi(row[13]) != ymin_type) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YMIN_TYPE; ZBX_DBROW2UINT64(graph->ymin_itemid, row[14]); if ((unsigned char)atoi(row[15]) != ymax_type) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YMAX_TYPE; ZBX_DBROW2UINT64(graph->ymax_itemid, row[16]); zbx_vector_ptr_create(&graph->gitems); zbx_vector_ptr_append(graphs, graph); } DBfree_result(result); zbx_vector_ptr_sort(graphs, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void execute_operations(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action) { const char *__function_name = "execute_operations"; DB_RESULT result; DB_ROW row; DB_OPERATION operation; int esc_period = 0, operations = 0; ZBX_USER_MSG *user_msg = NULL, *p; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (0 == action->esc_period) { result = DBselect( "select o.operationid,o.operationtype,o.esc_period,o.evaltype," "m.operationid,m.default_msg,subject,message,mediatypeid" " from operations o" " left join opmessage m" " on m.operationid=o.operationid" " where o.actionid=" ZBX_FS_UI64 " and o.operationtype in (%d,%d)", action->actionid, OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND); } else { escalation->esc_step++; result = DBselect( "select o.operationid,o.operationtype,o.esc_period,o.evaltype," "m.operationid,m.default_msg,subject,message,mediatypeid" " from operations o" " left join opmessage m" " on m.operationid=o.operationid" " where o.actionid=" ZBX_FS_UI64 " and o.operationtype in (%d,%d)" " and o.esc_step_from<=%d" " and (o.esc_step_to=0 or o.esc_step_to>=%d)", action->actionid, OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND, escalation->esc_step, escalation->esc_step); } while (NULL != (row = DBfetch(result))) { memset(&operation, 0, sizeof(operation)); ZBX_STR2UINT64(operation.operationid, row[0]); operation.actionid = action->actionid; operation.operationtype = atoi(row[1]); operation.esc_period = atoi(row[2]); operation.evaltype = (unsigned char)atoi(row[3]); if (SUCCEED == check_operation_conditions(event, operation.operationid, operation.evaltype)) { unsigned char default_msg; char *subject, *message; zbx_uint64_t mediatypeid; zabbix_log(LOG_LEVEL_DEBUG, "Conditions match our event. Execute operation."); if (0 == esc_period || esc_period > operation.esc_period) esc_period = operation.esc_period; switch (operation.operationtype) { case OPERATION_TYPE_MESSAGE: if (SUCCEED == DBis_null(row[4])) break; default_msg = (unsigned char)atoi(row[5]); ZBX_DBROW2UINT64(mediatypeid, row[8]); if (0 == default_msg) { subject = row[6]; message = row[7]; } else { subject = action->shortdata; message = action->longdata; } add_object_msg(operation.operationid, mediatypeid, &user_msg, subject, message, event->source, event->objectid); break; case OPERATION_TYPE_COMMAND: execute_commands(event, action->actionid, operation.operationid, escalation->esc_step); break; } } else zabbix_log(LOG_LEVEL_DEBUG, "Conditions do not match our event. Do not execute operation."); operations = 1; } DBfree_result(result); while (NULL != user_msg) { p = user_msg; user_msg = user_msg->next; add_message_alert(escalation, event, action, p->userid, p->mediatypeid, p->subject, p->message); zbx_free(p->subject); zbx_free(p->message); zbx_free(p); } if (0 == action->esc_period) { escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED; } else { if (0 == operations) { result = DBselect("select operationid from operations where actionid=" ZBX_FS_UI64 " and esc_step_from>%d", action->actionid, escalation->esc_step); if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0])) operations = 1; DBfree_result(result); } if (1 == operations) { esc_period = (0 != esc_period) ? esc_period : action->esc_period; escalation->nextcheck = time(NULL) + esc_period; } else escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: tm_execute_remote_command * * * * Purpose: execute remote command task * * * * Parameters: taskid - [IN] the task identifier * * clock - [IN] the task creation time * * ttl - [IN] the task expiration period in seconds * * now - [IN] the current time * * * * Return value: SUCCEED - the remote command was executed * * FAIL - otherwise * * * ******************************************************************************/ static int tm_execute_remote_command(zbx_uint64_t taskid, int clock, int ttl, int now) { DB_ROW row; DB_RESULT result; zbx_uint64_t parent_taskid, hostid; zbx_tm_task_t *task = NULL; int ret = FAIL; zbx_script_t script; char *info = NULL, error[MAX_STRING_LEN]; DC_HOST host; result = DBselect("select command_type,execute_on,port,authtype,username,password,publickey,privatekey," "command,parent_taskid,hostid" " from task_remote_command" " where taskid=" ZBX_FS_UI64, taskid); if (NULL == (row = DBfetch(result))) goto finish; task = zbx_tm_task_create(0, ZBX_TM_TASK_REMOTE_COMMAND_RESULT, ZBX_TM_STATUS_NEW, time(NULL), 0, 0); ZBX_STR2UINT64(parent_taskid, row[9]); if (0 != ttl && clock + ttl < now) { task->data = zbx_tm_remote_command_result_create(parent_taskid, FAIL, "The remote command has been expired."); goto finish; } ZBX_STR2UINT64(hostid, row[10]); if (FAIL == DCget_host_by_hostid(&host, hostid)) { task->data = zbx_tm_remote_command_result_create(parent_taskid, FAIL, "Unknown host."); goto finish; } zbx_script_init(&script); ZBX_STR2UCHAR(script.type, row[0]); ZBX_STR2UCHAR(script.execute_on, row[1]); script.port = (0 == atoi(row[2]) ? (char *)"" : row[2]); ZBX_STR2UCHAR(script.authtype, row[3]); script.username = row[4]; script.password = row[5]; script.publickey = row[6]; script.privatekey = row[7]; script.command = row[8]; if (ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT == script.type && ZBX_SCRIPT_EXECUTE_ON_PROXY == script.execute_on) { if (0 == CONFIG_ENABLE_REMOTE_COMMANDS) { task->data = zbx_tm_remote_command_result_create(parent_taskid, FAIL, "Remote commands are not enabled"); goto finish; } if (1 == CONFIG_LOG_REMOTE_COMMANDS) zabbix_log(LOG_LEVEL_WARNING, "Executing command '%s'", script.command); else zabbix_log(LOG_LEVEL_DEBUG, "Executing command '%s'", script.command); } if (SUCCEED != (ret = zbx_script_execute(&script, &host, &info, error, sizeof(error)))) task->data = zbx_tm_remote_command_result_create(parent_taskid, ret, error); else task->data = zbx_tm_remote_command_result_create(parent_taskid, ret, info); zbx_free(info); finish: DBfree_result(result); DBbegin(); if (NULL != task) { zbx_tm_save_task(task); zbx_tm_task_free(task); } DBexecute("update task set status=%d where taskid=" ZBX_FS_UI64, ZBX_TM_STATUS_DONE, taskid); DBcommit(); return ret; }