/****************************************************************************** * * * Function: hk_history_prepare * * * * Purpose: prepares history housekeeping rule * * * * Parameters: rule - [IN/OUT] the history housekeeping rule * * now - [IN] the current timestmap * * * * Author: Andris Zeila * * * * Comments: This function is called to initialize history rule data either * * at start or when housekeeping is enabled for this rule. * * It caches item history data and also prepares delete queue to be * * processed during the first run. * * * ******************************************************************************/ static void hk_history_prepare(zbx_hk_history_rule_t *rule, int now) { DB_RESULT result; DB_ROW row; zbx_hashset_create(&rule->item_cache, 1024, zbx_default_uint64_hash_func, zbx_default_uint64_compare_func); zbx_vector_ptr_create(&rule->delete_queue); zbx_vector_ptr_reserve(&rule->delete_queue, HK_INITIAL_DELETE_QUEUE_SIZE); result = DBselect("select itemid,min(clock) from %s group by itemid", rule->table); while (NULL != (row = DBfetch(result))) { zbx_uint64_t itemid; int min_clock; zbx_hk_item_cache_t item_record; ZBX_STR2UINT64(itemid, row[0]); min_clock = atoi(row[1]); item_record.itemid = itemid; item_record.min_clock = min_clock; zbx_hashset_insert(&rule->item_cache, &item_record, sizeof(zbx_hk_item_cache_t)); } DBfree_result(result); }
/****************************************************************************** * * * Function: DCflush_nextchecks * * * * Purpose: update triggers to UNKNOWN and generate events * * * ******************************************************************************/ void DCflush_nextchecks(zbx_vector_ptr_t *trigger_diff) { const char *__function_name = "DCflush_nextchecks"; int i; zbx_uint64_t *itemids = NULL; zbx_timespec_t *timespecs = NULL; char **errors = NULL; zbx_hashset_t trigger_info; zbx_vector_ptr_t trigger_order; DC_TRIGGER *trigger; zabbix_log(LOG_LEVEL_DEBUG, "In %s() nextcheck_num:%d", __function_name, nextcheck_num); if (0 == nextcheck_num) goto exit; itemids = zbx_malloc(itemids, nextcheck_num * sizeof(zbx_uint64_t)); timespecs = zbx_malloc(timespecs, nextcheck_num * sizeof(zbx_timespec_t)); errors = zbx_malloc(errors, nextcheck_num * sizeof(char *)); for (i = 0; i < nextcheck_num; i++) { itemids[i] = nextchecks[i].itemid; timespecs[i] = nextchecks[i].ts; errors[i] = nextchecks[i].error_msg; } zbx_hashset_create(&trigger_info, MAX(100, 2 * nextcheck_num), ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_ptr_create(&trigger_order); zbx_vector_ptr_reserve(&trigger_order, nextcheck_num); DCconfig_get_triggers_by_itemids(&trigger_info, &trigger_order, itemids, timespecs, errors, nextcheck_num, 0); zbx_free(errors); zbx_free(timespecs); zbx_free(itemids); for (i = 0; i < trigger_order.values_num; i++) { trigger = (DC_TRIGGER *)trigger_order.values[i]; trigger->new_value = TRIGGER_VALUE_UNKNOWN; } zbx_process_triggers(&trigger_order, trigger_diff); DCfree_triggers(&trigger_order); zbx_hashset_destroy(&trigger_info); zbx_vector_ptr_destroy(&trigger_order); DCclean_nextchecks(); exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: recv_getqueue * * * * Purpose: process queue request * * * * Parameters: sock - [IN] the request socket * * jp - [IN] the request data * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * ******************************************************************************/ static int recv_getqueue(zbx_socket_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "recv_getqueue"; int ret = FAIL, request_type = -1, now, i; char type[MAX_STRING_LEN], sessionid[MAX_STRING_LEN]; zbx_vector_ptr_t queue; struct zbx_json json; zbx_hashset_t queue_stats; zbx_queue_stats_t *stats; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SID, sessionid, sizeof(sessionid)) || FAIL == zbx_session_validate(sessionid, USER_TYPE_SUPER_ADMIN)) { zbx_send_response_raw(sock, ret, "Permission denied.", CONFIG_TIMEOUT); goto out; } if (FAIL != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, type, sizeof(type))) { if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_OVERVIEW)) request_type = ZBX_GET_QUEUE_OVERVIEW; else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_PROXY)) request_type = ZBX_GET_QUEUE_PROXY; else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_DETAILS)) request_type = ZBX_GET_QUEUE_DETAILS; } if (-1 == request_type) { zbx_send_response_raw(sock, ret, "Unsupported request type.", CONFIG_TIMEOUT); goto out; } now = time(NULL); zbx_vector_ptr_create(&queue); DCget_item_queue(&queue, 6, -1); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); switch (request_type) { case ZBX_GET_QUEUE_OVERVIEW: zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); /* gather queue stats by item type */ for (i = 0; i < queue.values_num; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_uint64_t id = item->type; if (NULL == (stats = zbx_hashset_search(&queue_stats, &id))) { zbx_queue_stats_t data = {id}; stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data)); } queue_stats_update(stats, now - item->nextcheck); } zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); queue_stats_export(&queue_stats, "itemtype", &json); zbx_hashset_destroy(&queue_stats); break; case ZBX_GET_QUEUE_PROXY: zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); /* gather queue stats by proxy hostid */ for (i = 0; i < queue.values_num; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_uint64_t id = item->proxy_hostid; if (NULL == (stats = zbx_hashset_search(&queue_stats, &id))) { zbx_queue_stats_t data = {id}; stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data)); } queue_stats_update(stats, now - item->nextcheck); } zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); queue_stats_export(&queue_stats, "proxyid", &json); zbx_hashset_destroy(&queue_stats); break; case ZBX_GET_QUEUE_DETAILS: zbx_vector_ptr_sort(&queue, (zbx_compare_func_t)queue_compare_by_nextcheck_asc); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); for (i = 0; i < queue.values_num && i <= 500; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_json_addobject(&json, NULL); zbx_json_adduint64(&json, "itemid", item->itemid); zbx_json_adduint64(&json, "nextcheck", item->nextcheck); zbx_json_close(&json); } zbx_json_close(&json); break; } zabbix_log(LOG_LEVEL_DEBUG, "%s() json.buffer:'%s'", __function_name, json.buffer); zbx_tcp_send_raw(sock, json.buffer); DCfree_item_queue(&queue); zbx_vector_ptr_destroy(&queue); zbx_json_free(&json); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
/****************************************************************************** * * * Function: db_get_query_functions * * * * Purpose: get event query functionids from database * * * ******************************************************************************/ static void db_get_query_functions(zbx_vector_ptr_t *event_queries) { DB_ROW row; DB_RESULT result; int i; zbx_vector_uint64_t triggerids; zbx_hashset_t triggers; zbx_hashset_iter_t iter; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_trigger_functions_t *trigger = NULL, trigger_local; zbx_uint64_t triggerid, functionid; zbx_event_suppress_query_t *query; /* cache functionids by triggerids */ zbx_hashset_create(&triggers, 100, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_uint64_create(&triggerids); for (i = 0; i < event_queries->values_num; i++) { query = (zbx_event_suppress_query_t *)event_queries->values[i]; zbx_vector_uint64_append(&triggerids, query->triggerid); } zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_uint64_uniq(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select functionid,triggerid from functions where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", triggerids.values, triggerids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by triggerid"); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(functionid, row[0]); ZBX_STR2UINT64(triggerid, row[1]); if (NULL == trigger || trigger->triggerid != triggerid) { trigger_local.triggerid = triggerid; trigger = (zbx_trigger_functions_t *)zbx_hashset_insert(&triggers, &trigger_local, sizeof(trigger_local)); zbx_vector_uint64_create(&trigger->functionids); } zbx_vector_uint64_append(&trigger->functionids, functionid); } DBfree_result(result); /* copy functionids to event queries */ for (i = 0; i < event_queries->values_num; i++) { query = (zbx_event_suppress_query_t *)event_queries->values[i]; if (NULL == (trigger = (zbx_trigger_functions_t *)zbx_hashset_search(&triggers, &query->triggerid))) continue; zbx_vector_uint64_append_array(&query->functionids, trigger->functionids.values, trigger->functionids.values_num); } zbx_hashset_iter_reset(&triggers, &iter); while (NULL != (trigger = (zbx_trigger_functions_t *)zbx_hashset_iter_next(&iter))) zbx_vector_uint64_destroy(&trigger->functionids); zbx_hashset_destroy(&triggers); zbx_vector_uint64_destroy(&triggerids); }