コード例 #1
0
/* detects service flapping */
void check_for_service_flapping(service *svc, int update, int allow_flapstart_notification) {
	int update_history = TRUE;
	int is_flapping = FALSE;
	register int x = 0;
	register int y = 0;
	int last_state_history_value = STATE_OK;
	double curved_changes = 0.0;
	double curved_percent_change = 0.0;
	double low_threshold = 0.0;
	double high_threshold = 0.0;
	double low_curve_value = 0.75;
	double high_curve_value = 1.25;

	/* large install tweaks skips all flap detection logic - including state change calculation */


	log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_service_flapping()\n");

	if (svc == NULL)
		return;

	log_debug_info(DEBUGL_FLAPPING, 1, "Checking service '%s' on host '%s' for flapping...\n", svc->description, svc->host_name);

	/* if this is a soft service state and not a soft recovery, don't record this in the history */
	/* only hard states and soft recoveries get recorded for flap detection */
	if (svc->state_type == SOFT_STATE && svc->current_state != STATE_OK)
		return;

	/* what threshold values should we use (global or service-specific)? */
	low_threshold = (svc->low_flap_threshold <= 0.0) ? low_service_flap_threshold : svc->low_flap_threshold;
	high_threshold = (svc->high_flap_threshold <= 0.0) ? high_service_flap_threshold : svc->high_flap_threshold;

	update_history = update;

	/* should we update state history for this state? */
	if (update_history == TRUE) {

		if (svc->current_state == STATE_OK  && svc->flap_detection_on_ok == FALSE)
			update_history = FALSE;
		if (svc->current_state == STATE_WARNING && svc->flap_detection_on_warning == FALSE)
			update_history = FALSE;
		if (svc->current_state == STATE_UNKNOWN && svc->flap_detection_on_unknown == FALSE)
			update_history = FALSE;
		if (svc->current_state == STATE_CRITICAL && svc->flap_detection_on_critical == FALSE)
			update_history = FALSE;
	}

	/* record current service state */
	if (update_history == TRUE) {

		/* record the current state in the state history */
		svc->state_history[svc->state_history_index] = svc->current_state;

		/* increment state history index to next available slot */
		svc->state_history_index++;
		if (svc->state_history_index >= MAX_STATE_HISTORY_ENTRIES)
			svc->state_history_index = 0;
	}

	/* calculate overall and curved percent state changes */
	for (x = 0, y = svc->state_history_index; x < MAX_STATE_HISTORY_ENTRIES; x++) {

		if (x == 0) {
			last_state_history_value = svc->state_history[y];
			y++;
			if (y >= MAX_STATE_HISTORY_ENTRIES)
				y = 0;
			continue;
		}

		if (last_state_history_value != svc->state_history[y])
			curved_changes += (((double)(x - 1) * (high_curve_value - low_curve_value)) / ((double)(MAX_STATE_HISTORY_ENTRIES - 2))) + low_curve_value;

		last_state_history_value = svc->state_history[y];

		y++;
		if (y >= MAX_STATE_HISTORY_ENTRIES)
			y = 0;
	}

	/* calculate overall percent change in state */
	curved_percent_change = (double)(((double)curved_changes * 100.0) / (double)(MAX_STATE_HISTORY_ENTRIES - 1));

	svc->percent_state_change = curved_percent_change;

	log_debug_info(DEBUGL_FLAPPING, 2, "LFT (low_threshold): %.2f, HFT (high_threshold): %.2f, CPC (curved_percent_change): %.2f, PSC (curved_percent_change): %.2f%%\n",
			low_threshold, high_threshold, curved_percent_change, curved_percent_change);


	/* don't do anything if we don't have flap detection enabled on a program-wide basis */
	if (enable_flap_detection == FALSE)
		return;

	/* don't do anything if we don't have flap detection enabled for this service */
	if (svc->flap_detection_enabled == FALSE)
		return;

	/* are we flapping, undecided, or what?... */

	/* we're undecided, so don't change the current flap state */
	if (curved_percent_change > low_threshold && curved_percent_change < high_threshold)
		return;

	/* we're below the lower bound, so we're not flapping */
	else if (curved_percent_change <= low_threshold)
		is_flapping = FALSE;

	/* else we're above the upper bound, so we are flapping */
	else if (curved_percent_change >= high_threshold)
		is_flapping = TRUE;

	log_debug_info(DEBUGL_FLAPPING, 1, "Service %s flapping (%.2f%% state change).\n", (is_flapping == TRUE) ? "is" : "is not", curved_percent_change);

	/* did the service just start flapping? */
	if (is_flapping == TRUE && svc->is_flapping == FALSE)
		set_service_flap(svc, curved_percent_change, high_threshold, low_threshold, allow_flapstart_notification);

	/* did the service just stop flapping? */
	else if (is_flapping == FALSE && svc->is_flapping == TRUE)
		clear_service_flap(svc, curved_percent_change, high_threshold, low_threshold);

	return;
}
コード例 #2
0
/* detects service flapping */
void check_for_service_flapping(service *svc, int update, int allow_flapstart_notification)
{
	int is_flapping = FALSE;
	double low_threshold = 0.0;
	double high_threshold = 0.0;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_service_flapping()\n");

	if (svc == NULL || !should_flap_detect(svc))
		return;

	log_debug_info(DEBUGL_FLAPPING, 1, "Checking service '%s' on host '%s' for flapping...\n", svc->description, svc->host_name);

	/* if this is a soft service state and not a soft recovery, don't record this in the history */
	/* only hard states and soft recoveries get recorded for flap detection */
	if (svc->state_type == SOFT_STATE && svc->current_state != STATE_OK)
		return;

	/*
	 * if we shouldn't update the state history with this state, flapping
	 * state won't change and we can just as well return early
	 */
	if (!update)
		return;

	/* what threshold values should we use (global or service-specific)? */
	low_threshold = (svc->low_flap_threshold <= 0.0) ? low_service_flap_threshold : svc->low_flap_threshold;
	high_threshold = (svc->high_flap_threshold <= 0.0) ? high_service_flap_threshold : svc->high_flap_threshold;

	/* record the current state in the state history */
	svc->state_history[svc->state_history_index] = svc->current_state;

	/* increment state history index to next available slot */
	svc->state_history_index++;
	if (svc->state_history_index >= MAX_STATE_HISTORY_ENTRIES)
		svc->state_history_index = 0;

	svc->percent_state_change = flapping_pct(svc->state_history, svc->state_history_index,
		                                     MAX_STATE_HISTORY_ENTRIES);

	log_debug_info(DEBUGL_FLAPPING, 2, "LFT=%.2f, HFT=%.2f, CPC=%.2f, PSC=%.2f%%\n", low_threshold, high_threshold, svc->percent_state_change, svc->percent_state_change);

	/* bail out now if flap detection is disabled */
	if (enable_flap_detection == FALSE)
		return;
	if (svc->flap_detection_enabled == FALSE)
		return;

	/* we're undecided, so don't change the current flap state */
	if (svc->percent_state_change > low_threshold && svc->percent_state_change < high_threshold)
		return;

	/* we're below the lower bound, so we're not flapping */
	if (svc->percent_state_change <= low_threshold)
		is_flapping = FALSE;

	/* else we're above the upper bound, so we are flapping */
	else if (svc->percent_state_change >= high_threshold)
		is_flapping = TRUE;

	log_debug_info(DEBUGL_FLAPPING, 1, "Service %s flapping (%.2f%% state change).\n", (is_flapping == TRUE) ? "is" : "is not", svc->percent_state_change);

	/* did the service just start flapping? */
	if (is_flapping == TRUE && svc->is_flapping == FALSE)
		set_service_flap(svc, svc->percent_state_change, high_threshold, low_threshold, allow_flapstart_notification);

	/* did the service just stop flapping? */
	else if (is_flapping == FALSE && svc->is_flapping == TRUE)
		clear_service_flap(svc, svc->percent_state_change, high_threshold, low_threshold);
}