Ejemplo n.º 1
0
/* this function gets called when the module is loaded by the event broker */
int nebmodule_init(int flags, char *args, nebmodule *handle) {
	char temp_buffer[1024];
	time_t current_time;
	unsigned long interval;

	/* save our handle */
	helloworld_module_handle = handle;

	/* set some info - this is completely optional, as Nagios doesn't do anything with this data */
	neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_TITLE, "helloworld");
	neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_AUTHOR, "Ethan Galstad");
	neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_TITLE, "Copyright (c) 2003-2007 Ethan Galstad");
	neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_VERSION, "noversion");
	neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_LICENSE, "GPL v2");
	neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_DESC, "A simple example to get you started with Nagios Event Broker (NEB) modules.");

	/* log module info to the Nagios log file */
	logit(NSLOG_INFO_MESSAGE,
	      "helloworld: Copyright (c) 2003-2007 Ethan Galstad ([email protected])");

	/* log a message to the Nagios log file */
	snprintf(temp_buffer, sizeof(temp_buffer) - 1, "helloworld: Hello world!\n");
	temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
	logit(NSLOG_INFO_MESSAGE, temp_buffer);

	/* log a reminder message every 15 minutes (how's that for annoying? :-)) */
	time(&current_time);
	interval = 900;
	schedule_new_event(EVENT_USER_FUNCTION, TRUE, current_time + interval, TRUE, interval, NULL, TRUE, (void *)helloworld_reminder_message, "How about you?", 0);

	/* register to be notified of certain events... */
	neb_register_callback(NEBCALLBACK_AGGREGATED_STATUS_DATA, helloworld_module_handle, 0, helloworld_handle_data);

	return 0;
	}
Ejemplo n.º 2
0
/* checks for flexible (non-fixed) service downtime that should start now */
int check_pending_flex_service_downtime(service *svc) {
	scheduled_downtime *temp_downtime = NULL;
	time_t current_time = 0L;
	unsigned long * new_downtime_id = NULL;


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

	if(svc == NULL)
		return ERROR;

	time(&current_time);

	/* if service is currently ok, nothing to do */
	if(svc->current_state == STATE_OK)
		return OK;

	/* check all downtime entries */
	for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) {

		if(temp_downtime->type != SERVICE_DOWNTIME)
			continue;

		if(temp_downtime->fixed == TRUE)
			continue;

		if(temp_downtime->is_in_effect == TRUE)
			continue;

		/* triggered downtime entries should be ignored here */
		if(temp_downtime->triggered_by != 0)
			continue;

		/* this entry matches our service! */
		if(find_service(temp_downtime->host_name, temp_downtime->service_description) == svc) {

			/* if the time boundaries are okay, start this scheduled downtime */
			if(temp_downtime->start_time <= current_time && current_time <= temp_downtime->end_time) {

				log_debug_info(DEBUGL_DOWNTIME, 0, "Flexible downtime (id=%lu) for service '%s' on host '%s' starting now...\n", temp_downtime->downtime_id, svc->description, svc->host_name);

				temp_downtime->flex_downtime_start = current_time;
				if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
					*new_downtime_id = temp_downtime->downtime_id;
					temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->flex_downtime_start, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
					}
				}
			}
		}

	return OK;
	}
Ejemplo n.º 3
0
/* checks for flexible (non-fixed) host downtime that should start now */
int check_pending_flex_host_downtime(host *hst) {
	scheduled_downtime *temp_downtime = NULL;
	time_t current_time = 0L;
	unsigned long * new_downtime_id = NULL;


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

	if(hst == NULL)
		return ERROR;

	time(&current_time);

	/* if host is currently up, nothing to do */
	if(hst->current_state == HOST_UP)
		return OK;

	/* check all downtime entries */
	for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) {

		if(temp_downtime->type != HOST_DOWNTIME)
			continue;

		if(temp_downtime->fixed == TRUE)
			continue;

		if(temp_downtime->is_in_effect == TRUE)
			continue;

		/* triggered downtime entries should be ignored here */
		if(temp_downtime->triggered_by != 0)
			continue;

		/* this entry matches our host! */
		if(find_host(temp_downtime->host_name) == hst) {

			/* if the time boundaries are okay, start this scheduled downtime */
			if(temp_downtime->start_time <= current_time && current_time <= temp_downtime->end_time) {

				log_debug_info(DEBUGL_DOWNTIME, 0, "Flexible downtime (id=%lu) for host '%s' starting now...\n", temp_downtime->downtime_id, hst->name);
				temp_downtime->flex_downtime_start = current_time;
				if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long)))) {
					*new_downtime_id = temp_downtime->downtime_id;
					temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->flex_downtime_start, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
					}
				}
			}
		}

	return OK;
	}
Ejemplo n.º 4
0
/* adds a new host or service comment */
int add_new_comment(int type, int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id) {
	int result;
	unsigned long new_comment_id = 0L;

	if(type == HOST_COMMENT)
		result = add_new_host_comment(entry_type, host_name, entry_time, author_name, comment_data, persistent, source, expires, expire_time, &new_comment_id);
	else
		result = add_new_service_comment(entry_type, host_name, svc_description, entry_time, author_name, comment_data, persistent, source, expires, expire_time, &new_comment_id);

	/* add an event to expire comment data if necessary... */
	if(expires == TRUE)
		schedule_new_event(EVENT_EXPIRE_COMMENT, FALSE, expire_time, FALSE, 0, NULL, TRUE, (void *)new_comment_id, NULL, 0);

	/* save comment id */
	if(comment_id != NULL)
		*comment_id = new_comment_id;

	return result;
	}
Ejemplo n.º 5
0
/* initializes performance data */
int xpddefault_initialize_performance_data(const char *cfgfile)
{
	char *buffer = NULL;
	char *temp_buffer = NULL;
	command *temp_command = NULL;
	time_t current_time;
	nagios_macros *mac;

	mac = get_global_macros();
	time(&current_time);

	/* reset vars */
	host_perfdata_command_ptr = NULL;
	service_perfdata_command_ptr = NULL;
	host_perfdata_file_processing_command_ptr = NULL;
	service_perfdata_file_processing_command_ptr = NULL;

	/* make sure we have some templates defined */
	if (host_perfdata_file_template == NULL)
		host_perfdata_file_template = (char *)strdup(DEFAULT_HOST_PERFDATA_FILE_TEMPLATE);
	if (service_perfdata_file_template == NULL)
		service_perfdata_file_template = (char *)strdup(DEFAULT_SERVICE_PERFDATA_FILE_TEMPLATE);

	/* process special chars in templates */
	xpddefault_preprocess_file_templates(host_perfdata_file_template);
	xpddefault_preprocess_file_templates(service_perfdata_file_template);

	/* open the performance data files */
	xpddefault_open_host_perfdata_file();
	xpddefault_open_service_perfdata_file();

	/* verify that performance data commands are valid */
	if (host_perfdata_command != NULL) {
		temp_buffer = (char *)strdup(host_perfdata_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host performance command '%s' was not found - host performance data will not be processed!\n", host_perfdata_command);
			my_free(host_perfdata_command);
		}

		my_free(temp_buffer);

		/* save the command pointer for later */
		host_perfdata_command_ptr = temp_command;
	}

	if (service_perfdata_command != NULL) {
		temp_buffer = (char *)strdup(service_perfdata_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Service performance command '%s' was not found - service performance data will not be processed!\n", service_perfdata_command);
			my_free(service_perfdata_command);
		}

		my_free(temp_buffer);

		/* save the command pointer for later */
		service_perfdata_command_ptr = temp_command;
	}

	if (host_perfdata_file_processing_command != NULL) {
		temp_buffer = (char *)strdup(host_perfdata_file_processing_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host performance file processing command '%s' was not found - host performance data file will not be processed!\n", host_perfdata_file_processing_command);
			my_free(host_perfdata_file_processing_command);
		}

		/* free memory */
		my_free(temp_buffer);

		/* save the command pointer for later */
		host_perfdata_file_processing_command_ptr = temp_command;
	}

	if (service_perfdata_file_processing_command != NULL) {
		temp_buffer = (char *)strdup(service_perfdata_file_processing_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Service performance file processing command '%s' was not found - service performance data file will not be processed!\n", service_perfdata_file_processing_command);
			my_free(service_perfdata_file_processing_command);
		}

		/* save the command pointer for later */
		service_perfdata_file_processing_command_ptr = temp_command;
	}

	/* periodically process the host perfdata file */
	if (host_perfdata_file_processing_interval > 0 && host_perfdata_file_processing_command != NULL)
		schedule_new_event(EVENT_USER_FUNCTION, TRUE, current_time + host_perfdata_file_processing_interval, TRUE, host_perfdata_file_processing_interval, NULL, TRUE, (void *)xpddefault_process_host_perfdata_file, NULL, 0);

	/* periodically process the service perfdata file */
	if (service_perfdata_file_processing_interval > 0 && service_perfdata_file_processing_command != NULL)
		schedule_new_event(EVENT_USER_FUNCTION, TRUE, current_time + service_perfdata_file_processing_interval, TRUE, service_perfdata_file_processing_interval, NULL, TRUE, (void *)xpddefault_process_service_perfdata_file, NULL, 0);

	/* save the host perf data file macro */
	my_free(mac->x[MACRO_HOSTPERFDATAFILE]);
	if (host_perfdata_file != NULL) {
		if ((mac->x[MACRO_HOSTPERFDATAFILE] = (char *)strdup(host_perfdata_file)))
			strip(mac->x[MACRO_HOSTPERFDATAFILE]);
	}

	/* save the service perf data file macro */
	my_free(mac->x[MACRO_SERVICEPERFDATAFILE]);
	if (service_perfdata_file != NULL) {
		if ((mac->x[MACRO_SERVICEPERFDATAFILE] = (char *)strdup(service_perfdata_file)))
			strip(mac->x[MACRO_SERVICEPERFDATAFILE]);
	}

	/* free memory */
	my_free(temp_buffer);
	my_free(buffer);

	return OK;
}
Ejemplo n.º 6
0
/* initialize the event timing loop before we start monitoring */
void init_timing_loop(void)
{
	host *temp_host = NULL;
	service *temp_service = NULL;
	time_t current_time = 0L;
	struct timeval tv[9];
	double runtime[9];
	struct timeval now;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() start\n");

	/* get the time and seed the prng */
	gettimeofday(&now, NULL);
	current_time = now.tv_sec;
	srand((now.tv_sec << 10) ^ now.tv_usec);


	/******** GET BASIC HOST/SERVICE INFO  ********/

	memset(&scheduling_info, 0, sizeof(scheduling_info));

	if (test_scheduling == TRUE)
		gettimeofday(&tv[0], NULL);

	/* get info on service checks to be scheduled */
	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
		scheduling_info.total_services++;

		/* maybe we shouldn't schedule this check */
		if (temp_service->check_interval == 0 || !temp_service->checks_enabled) {
			log_debug_info(DEBUGL_EVENTS, 1, "Service '%s' on host '%s' should not be scheduled.\n", temp_service->description, temp_service->host_name);
			temp_service->should_be_scheduled = FALSE;
			continue;
		}

		scheduling_info.total_scheduled_services++;
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[1], NULL);

	/* get info on host checks to be scheduled */
	for (temp_host = host_list; temp_host; temp_host = temp_host->next) {
		scheduling_info.total_hosts++;

		/* host has no check interval */
		if (temp_host->check_interval == 0 || !temp_host->checks_enabled) {
			log_debug_info(DEBUGL_EVENTS, 1, "Host '%s' should not be scheduled.\n", temp_host->name);
			temp_host->should_be_scheduled = FALSE;
			continue;
		}

		scheduling_info.total_scheduled_hosts++;
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[2], NULL);

	scheduling_info.average_services_per_host = (double)((double)scheduling_info.total_services / (double)scheduling_info.total_hosts);
	scheduling_info.average_scheduled_services_per_host = (double)((double)scheduling_info.total_scheduled_services / (double)scheduling_info.total_hosts);

	/* adjust the check interval total to correspond to the interval length */
	scheduling_info.service_check_interval_total = (scheduling_info.service_check_interval_total * interval_length);

	/* calculate the average check interval for services */
	scheduling_info.average_service_check_interval = (double)((double)scheduling_info.service_check_interval_total / (double)scheduling_info.total_scheduled_services);

	if (test_scheduling == TRUE)
		gettimeofday(&tv[3], NULL);

	/******** SCHEDULE SERVICE CHECKS  ********/

	log_debug_info(DEBUGL_EVENTS, 2, "Scheduling service checks...");

	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
		log_debug_info(DEBUGL_EVENTS, 2, "Service '%s' on host '%s'\n", temp_service->description, temp_service->host_name);
		/* skip this service if it shouldn't be scheduled */
		if (temp_service->should_be_scheduled == FALSE) {
			continue;
		}

		temp_service->next_check = current_time + ranged_urand(0, check_window(temp_service));

		if (scheduling_info.last_service_check < temp_service->next_check)
			scheduling_info.last_service_check = temp_service->next_check;
		if (!scheduling_info.first_service_check || scheduling_info.first_service_check > temp_service->next_check)
			scheduling_info.first_service_check = temp_service->next_check;

		log_debug_info(DEBUGL_EVENTS, 2, "Check Time: %lu --> %s", (unsigned long)temp_service->next_check, ctime(&temp_service->next_check));
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[4], NULL);

	/* add scheduled service checks to event queue */
	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {

		/* update status of all services (scheduled or not) */
		update_service_status(temp_service, FALSE);

		/* skip most services that shouldn't be scheduled */
		if (temp_service->should_be_scheduled == FALSE) {

			/* passive checks are an exception if a forced check was scheduled before we restarted */
			if (!(temp_service->checks_enabled == FALSE && temp_service->next_check != (time_t)0L && (temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION)))
				continue;
		}

		/* create a new service check event */
		temp_service->next_check_event = schedule_new_event(EVENT_SERVICE_CHECK, FALSE, temp_service->next_check, FALSE, 0, NULL, TRUE, (void *)temp_service, NULL, temp_service->check_options);
	}


	if (test_scheduling == TRUE)
		gettimeofday(&tv[5], NULL);

	if (test_scheduling == TRUE)
		gettimeofday(&tv[6], NULL);


	/******** SCHEDULE HOST CHECKS  ********/

	log_debug_info(DEBUGL_EVENTS, 2, "Scheduling host checks...");

	/* determine check times for host checks */
	for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {

		log_debug_info(DEBUGL_EVENTS, 2, "Host '%s'\n", temp_host->name);

		/* skip hosts that shouldn't be scheduled */
		if (temp_host->should_be_scheduled == FALSE) {
			continue;
		}

		temp_host->next_check = current_time + ranged_urand(0, check_window(temp_host));

		log_debug_info(DEBUGL_EVENTS, 2, "Check Time: %lu --> %s", (unsigned long)temp_host->next_check, ctime(&temp_host->next_check));
		if (temp_host->next_check > scheduling_info.last_host_check)
			scheduling_info.last_host_check = temp_host->next_check;
		if (!scheduling_info.first_host_check || scheduling_info.first_host_check > temp_host->next_check)
			scheduling_info.first_host_check = temp_host->next_check;
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[7], NULL);

	/* add scheduled host checks to event queue */
	for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {

		/* update status of all hosts (scheduled or not) */
		update_host_status(temp_host, FALSE);

		/* skip most hosts that shouldn't be scheduled */
		if (temp_host->should_be_scheduled == FALSE) {

			/* passive checks are an exception if a forced check was scheduled before Nagios was restarted */
			if (!(temp_host->checks_enabled == FALSE && temp_host->next_check != (time_t)0L && (temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION)))
				continue;
		}

		/* schedule a new host check event */
		temp_host->next_check_event = schedule_new_event(EVENT_HOST_CHECK, FALSE, temp_host->next_check, FALSE, 0, NULL, TRUE, (void *)temp_host, NULL, temp_host->check_options);
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[8], NULL);


	/******** SCHEDULE MISC EVENTS ********/

	/* add a check result reaper event */
	schedule_new_event(EVENT_CHECK_REAPER, TRUE, current_time + check_reaper_interval, TRUE, check_reaper_interval, NULL, TRUE, NULL, NULL, 0);

	/* add an orphaned check event */
	if (check_orphaned_services == TRUE || check_orphaned_hosts == TRUE)
		schedule_new_event(EVENT_ORPHAN_CHECK, TRUE, current_time + DEFAULT_ORPHAN_CHECK_INTERVAL, TRUE, DEFAULT_ORPHAN_CHECK_INTERVAL, NULL, TRUE, NULL, NULL, 0);

	/* add a service result "freshness" check event */
	if (check_service_freshness == TRUE)
		schedule_new_event(EVENT_SFRESHNESS_CHECK, TRUE, current_time + service_freshness_check_interval, TRUE, service_freshness_check_interval, NULL, TRUE, NULL, NULL, 0);

	/* add a host result "freshness" check event */
	if (check_host_freshness == TRUE)
		schedule_new_event(EVENT_HFRESHNESS_CHECK, TRUE, current_time + host_freshness_check_interval, TRUE, host_freshness_check_interval, NULL, TRUE, NULL, NULL, 0);

	/* add a status save event */
	schedule_new_event(EVENT_STATUS_SAVE, TRUE, current_time + status_update_interval, TRUE, status_update_interval, NULL, TRUE, NULL, NULL, 0);

	/* add a retention data save event if needed */
	if (retain_state_information == TRUE && retention_update_interval > 0)
		schedule_new_event(EVENT_RETENTION_SAVE, TRUE, current_time + (retention_update_interval * 60), TRUE, (retention_update_interval * 60), NULL, TRUE, NULL, NULL, 0);

	if (test_scheduling == TRUE) {

		runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0);
		runtime[1] = (double)((double)(tv[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0);
		runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0);
		runtime[3] = (double)((double)(tv[4].tv_sec - tv[3].tv_sec) + (double)((tv[4].tv_usec - tv[3].tv_usec) / 1000.0) / 1000.0);
		runtime[4] = (double)((double)(tv[5].tv_sec - tv[4].tv_sec) + (double)((tv[5].tv_usec - tv[4].tv_usec) / 1000.0) / 1000.0);
		runtime[5] = (double)((double)(tv[6].tv_sec - tv[5].tv_sec) + (double)((tv[6].tv_usec - tv[5].tv_usec) / 1000.0) / 1000.0);
		runtime[6] = (double)((double)(tv[7].tv_sec - tv[6].tv_sec) + (double)((tv[7].tv_usec - tv[6].tv_usec) / 1000.0) / 1000.0);
		runtime[7] = (double)((double)(tv[8].tv_sec - tv[7].tv_sec) + (double)((tv[8].tv_usec - tv[7].tv_usec) / 1000.0) / 1000.0);

		runtime[8] = (double)((double)(tv[8].tv_sec - tv[0].tv_sec) + (double)((tv[8].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0);

		printf("EVENT SCHEDULING TIMES\n");
		printf("-------------------------------------\n");
		printf("Get service info:        %.6lf sec\n", runtime[0]);
		printf("Get host info info:      %.6lf sec\n", runtime[1]);
		printf("Get service params:      %.6lf sec\n", runtime[2]);
		printf("Schedule service times:  %.6lf sec\n", runtime[3]);
		printf("Schedule service events: %.6lf sec\n", runtime[4]);
		printf("Get host params:         %.6lf sec\n", runtime[5]);
		printf("Schedule host times:     %.6lf sec\n", runtime[6]);
		printf("Schedule host events:    %.6lf sec\n", runtime[7]);
		printf("                         ============\n");
		printf("TOTAL:                   %.6lf sec\n", runtime[8]);
		printf("\n\n");
	}

	log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() end\n");

	return;
}
Ejemplo n.º 7
0
/* handles scheduled host or service downtime */
int handle_scheduled_downtime(scheduled_downtime *temp_downtime) {
	scheduled_downtime *this_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	time_t event_time = 0L;
	time_t current_time = 0L;
	unsigned long *new_downtime_id = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif


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

	if (temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if (temp_downtime->type == HOST_DOWNTIME) {
		if ((hst = find_host(temp_downtime->host_name)) == NULL)
			return ERROR;
	} else {
		if ((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL)
			return ERROR;
	}

	/* if downtime if flexible and host/svc is in an ok state, don't do anything right now (wait for event handler to kick it off) */
	/* start_flex_downtime variable is set to TRUE by event handler functions */
	if (temp_downtime->fixed == FALSE) {

		/* we're not supposed to force a start of flex downtime... */
		if (temp_downtime->start_flex_downtime == FALSE) {

			/* host is up or service is ok, so we don't really do anything right now */
			if ((temp_downtime->type == HOST_DOWNTIME && hst->current_state == HOST_UP) || (temp_downtime->type == SERVICE_DOWNTIME && svc->current_state == STATE_OK)) {

				/* increment pending flex downtime counter */
				if (temp_downtime->type == HOST_DOWNTIME)
					hst->pending_flex_downtime++;
				else
					svc->pending_flex_downtime++;
				temp_downtime->incremented_pending_downtime = TRUE;

				/*** SINCE THE FLEX DOWNTIME MAY NEVER START, WE HAVE TO PROVIDE A WAY OF EXPIRING UNUSED DOWNTIME... ***/

				schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0);

				return OK;
			}
		}
	}

	time(&current_time);

	/* have we come to the end of the scheduled downtime? */
	if (temp_downtime->is_in_effect == TRUE && ( /* downtime needs to be in effect and ... */
		(temp_downtime->fixed == TRUE && current_time >= temp_downtime->end_time) || /* fixed downtime, endtime means end of downtime */
		(temp_downtime->fixed == FALSE && current_time >= (temp_downtime->trigger_time+temp_downtime->duration)) /* flexible downtime, endtime of downtime is trigger_time+duration */
	)){

		if (temp_downtime->type == HOST_DOWNTIME)
			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration);
		else
			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration);


#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_NORMAL;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time);
#endif

		/* decrement the downtime depth variable */
		if (temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth--;
		else
			svc->scheduled_downtime_depth--;

		if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name);

			/* send a notification */
			host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
		}

		else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
		}


		/* update the status data */
		if (temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* decrement pending flex downtime if necessary */
		if (temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
			if (temp_downtime->type == HOST_DOWNTIME) {
				if (hst->pending_flex_downtime > 0)
					hst->pending_flex_downtime--;
			} else {
				if (svc->pending_flex_downtime > 0)
					svc->pending_flex_downtime--;
			}
		}

		/* handle (stop) downtime that is triggered by this one */
		while (1) {

			/* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */
			for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
				if (this_downtime->triggered_by == temp_downtime->downtime_id) {
					handle_scheduled_downtime(this_downtime);
					break;
				}
			}

			if (this_downtime == NULL)
				break;
		}

		/* delete downtime entry */
		if (temp_downtime->type == HOST_DOWNTIME)
			delete_host_downtime(temp_downtime->downtime_id);
		else
			delete_service_downtime(temp_downtime->downtime_id);
	}

	/* else we are just starting the scheduled downtime */
	else {
		if (temp_downtime->type == HOST_DOWNTIME)
			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration);
		else
			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration);

		/* this happens after restart of icinga */
		if (temp_downtime->is_in_effect != TRUE) {
			if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

				/* set the trigger time, needed to detect the end of a flexible downtime */
				temp_downtime->trigger_time = current_time;

				log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", hst->name, temp_downtime->downtime_id, temp_downtime->trigger_time);

				/* log a notice - this one is parsed by the history CGI */
				logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name);

				/* send a notification */
				host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}

			else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

				/* set the trigger time, needed to detect the end of a flexible downtime */
				temp_downtime->trigger_time = current_time;

				log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", svc->description, svc->host_name, temp_downtime->downtime_id, temp_downtime->trigger_time);

				/* log a notice - this one is parsed by the history CGI */
				logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description);

				/* send a notification */
				service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}
		}

		/* increment the downtime depth variable */
		if (temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth++;
		else
			svc->scheduled_downtime_depth++;

		/* set the in effect flag */
		temp_downtime->is_in_effect = TRUE;

#ifdef USE_EVENT_BROKER
		/* send data to broker AFTER we know trigger_time, is_in_effect, and downtime_depth */
		broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time);
#endif
		/* update the status data */
		if (temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* schedule an event */
		if (temp_downtime->fixed == FALSE)
			event_time = (time_t)((unsigned long)time(NULL) + temp_downtime->duration);
		else
			event_time = temp_downtime->end_time;

		if ((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = temp_downtime->downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
		}

		/* handle (start) downtime that is triggered by this one */
		for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
			if (this_downtime->triggered_by == temp_downtime->downtime_id)
				handle_scheduled_downtime(this_downtime);
		}
	}

	return OK;
}
Ejemplo n.º 8
0
/* registers scheduled downtime (schedules it, adds comments, etc.) */
int register_downtime(int type, unsigned long downtime_id) {
	char *temp_buffer = NULL;
	char start_time_string[MAX_DATETIME_LENGTH] = "";
	char end_time_string[MAX_DATETIME_LENGTH] = "";
	scheduled_downtime *temp_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	char *type_string = NULL;
	int hours = 0;
	int minutes = 0;
	int seconds = 0;
	unsigned long *new_downtime_id = NULL;

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

	/* find the downtime entry in memory */
	temp_downtime = find_downtime(type, downtime_id);
	if (temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if (temp_downtime->type == HOST_DOWNTIME) {
		if ((hst = find_host(temp_downtime->host_name)) == NULL)
			return ERROR;
	} else {
		if ((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL)
			return ERROR;
	}

	/* create the comment */
	get_datetime_string(&(temp_downtime->start_time), start_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->end_time), end_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	hours = temp_downtime->duration / 3600;
	minutes = ((temp_downtime->duration - (hours * 3600)) / 60);
	seconds = temp_downtime->duration - (hours * 3600) - (minutes * 60);
	if (temp_downtime->type == HOST_DOWNTIME)
		type_string = "host";
	else
		type_string = "service";
	if (temp_downtime->fixed == TRUE)
		asprintf(&temp_buffer, "This %s has been scheduled for fixed downtime from %s to %s.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, type_string);
	else
		asprintf(&temp_buffer, "This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, hours, minutes, type_string);


	log_debug_info(DEBUGL_DOWNTIME, 0, "Scheduled Downtime Details:\n");
	if (temp_downtime->type == HOST_DOWNTIME) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Host Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", hst->name);
	} else {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Service Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", svc->host_name);
		log_debug_info(DEBUGL_DOWNTIME, 0, " Service:     %s\n", svc->description);
	}
	log_debug_info(DEBUGL_DOWNTIME, 0, " Fixed/Flex:  %s\n", (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible");
	log_debug_info(DEBUGL_DOWNTIME, 0, " Start:       %s\n", start_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " End:         %s\n", end_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Duration:    %dh %dm %ds\n", hours, minutes, seconds);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Downtime ID: %lu\n", temp_downtime->downtime_id);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Trigger ID:  %lu\n", temp_downtime->triggered_by);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Author:      %s\n", (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"));


	/* add a non-persistent comment to the host or service regarding the scheduled outage */
	if (temp_downtime->type == SERVICE_DOWNTIME)
		add_new_comment(SERVICE_COMMENT, DOWNTIME_COMMENT, svc->host_name, svc->description, time(NULL), (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));
	else
		add_new_comment(HOST_COMMENT, DOWNTIME_COMMENT, hst->name, NULL, time(NULL), (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));

	/* free comment buffer */
	my_free(temp_buffer);

	/*** SCHEDULE DOWNTIME - FLEXIBLE (NON-FIXED) DOWNTIME IS HANDLED AT A LATER POINT ***/

	/* only non-triggered downtime is scheduled... */
	if (temp_downtime->triggered_by == 0) {
		if ((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
		}
	}

#ifdef PROBABLY_NOT_NEEDED
	/*** FLEXIBLE DOWNTIME SANITY CHECK - ADDED 02/17/2008 ****/

	/* if host/service is in a non-OK/UP state right now, see if we should start flexible time immediately */
	/* this is new logic added in 3.0rc3 */
	if (temp_downtime->fixed == FALSE) {
		if (temp_downtime->type == HOST_DOWNTIME)
			check_pending_flex_host_downtime(hst);
		else
			check_pending_flex_service_downtime(svc);
	}
#endif

	return OK;
}
Ejemplo n.º 9
0
/* this function gets called when the module is loaded by the event broker */
int nebmodule_init(int flags, char *args, nebmodule *handle) {
	char temp_buffer[1024];
	time_t current_time;
	unsigned long interval;

	/* save our handle */
	npcdmod_module_handle = handle;

	/* set some info - this is completely optional, as Nagios doesn't do anything with this data */
	neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_TITLE, "npcdmod");
	neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_AUTHOR, "Hendrik Baecker");
	neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_TITLE, "Copyright (c) 2008-2009 Hendrik Baecker");
	neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_VERSION, "0.0.2");
	neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_LICENSE, "GPL v2");
	neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_DESC, "A simple performance data extractor.");

	/* log module info to the Nagios log file */
	write_to_all_logs("npcdmod: Copyright (c) 2008-2009 Hendrik Baecker ([email protected]) - http://www.pnp4nagios.org", NSLOG_INFO_MESSAGE);

	if (process_performance_data == FALSE) {
		write_to_all_logs("npcdmod: I can not work with disabled performance data in nagios.cfg.", NSLOG_INFO_MESSAGE);
		write_to_all_logs("npcdmod: Please enable it with 'process_performance_data=1' in nagios.cfg", NSLOG_INFO_MESSAGE);
		return -1;
	}

	/* process arguments */
	if (npcdmod_process_module_args(args) == ERROR) {
		write_to_all_logs("npcdmod: An error occurred while attempting to process module arguments.", NSLOG_INFO_MESSAGE);
		return -1;
	}

	/* de-initialize if there is no perfdata file nor spool dir */
	if (spool_dir == NULL || perfdata_file == NULL) {
		write_to_all_logs("npcdmod: An error occurred process your config file. Check your perfdata_file or perfdata_spool_dir.", NSLOG_INFO_MESSAGE);
		return -1;
	}

	/* Log some health data */
	snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: spool_dir = '%s'.", spool_dir, NSLOG_INFO_MESSAGE);
	temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
	write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE);

	snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: perfdata file '%s'.", perfdata_file, NSLOG_INFO_MESSAGE);
	temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
	write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE);

	/* open perfdata_file to write perfdata in it */
	if ((fp = fopen(perfdata_file, "a")) == NULL) {
		snprintf(temp_buffer, sizeof(temp_buffer) - 1,
				"npcdmod: Could not open file. %s", strerror(errno),
				NSLOG_INFO_MESSAGE);
		temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
		write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE);
		return -1;
	}

	/* log a message to the Nagios log file that we're ready */
	snprintf(temp_buffer, sizeof(temp_buffer) - 1,
			"npcdmod: Ready to run to have some fun!\n");
	temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
	write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE);

	/* write_to_all_logs("\x62\x68\040\x64\145\x6b\162\157\167\040\145\162\145\150", NSLOG_INFO_MESSAGE); */
	/* register for a 15 seconds file move event */
	time(&current_time);
	interval = 15;
	schedule_new_event(EVENT_USER_FUNCTION,TRUE, current_time + interval, TRUE,
	interval, NULL, TRUE, (void *) npcdmod_file_roller, "", 0);

	/* register to be notified of certain events... */
	neb_register_callback(NEBCALLBACK_HOST_CHECK_DATA, npcdmod_module_handle,
			0, npcdmod_handle_data);
	neb_register_callback(NEBCALLBACK_SERVICE_CHECK_DATA,
	npcdmod_module_handle, 0, npcdmod_handle_data);
	return 0;
}
Ejemplo n.º 10
0
/* handles scheduled host or service downtime */
int handle_scheduled_downtime(scheduled_downtime *temp_downtime) {
	scheduled_downtime *this_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	time_t event_time = 0L;
	unsigned long *new_downtime_id = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif


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

	if(temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if(temp_downtime->type == HOST_DOWNTIME) {
		if((hst = find_host(temp_downtime->host_name)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find host (%s) for downtime\n", temp_downtime->host_name);
			return ERROR;
			}
		}
	else {
		if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find service (%s) host (%s) for downtime\n", temp_downtime->service_description, temp_downtime->host_name);
			return ERROR;
			}
		}

	/* have we come to the end of the scheduled downtime? */
	if(temp_downtime->is_in_effect == TRUE) {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_NORMAL;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL);
#endif

		/* decrement the downtime depth variable */
		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth > 0)
			hst->scheduled_downtime_depth--;
		else if (svc->scheduled_downtime_depth > 0)
			svc->scheduled_downtime_depth--;

		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name);

			/* send a notification */
			host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}

		else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}


		/* update the status data */
		if(temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* decrement pending flex downtime if necessary */
		if(temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
			if(temp_downtime->type == HOST_DOWNTIME) {
				if(hst->pending_flex_downtime > 0)
					hst->pending_flex_downtime--;
				}
			else {
				if(svc->pending_flex_downtime > 0)
					svc->pending_flex_downtime--;
				}
			}

		/* handle (stop) downtime that is triggered by this one */
		while(1) {

			/* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */
			for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
				if(this_downtime->triggered_by == temp_downtime->downtime_id) {
					handle_scheduled_downtime(this_downtime);
					break;
					}
				}

			if(this_downtime == NULL)
				break;
			}

		/* delete downtime entry */
		if(temp_downtime->type == HOST_DOWNTIME)
			delete_host_downtime(temp_downtime->downtime_id);
		else
			delete_service_downtime(temp_downtime->downtime_id);
		}

	/* else we are just starting the scheduled downtime */
	else {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL);
#endif

		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name);

			/* send a notification */
			if( FALSE == temp_downtime->start_notification_sent) {
				host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
				temp_downtime->start_notification_sent = TRUE;
				}
			}

		else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			if( FALSE == temp_downtime->start_notification_sent) {
				service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
				temp_downtime->start_notification_sent = TRUE;
				}
			}

		/* increment the downtime depth variable */
		if(temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth++;
		else
			svc->scheduled_downtime_depth++;

		/* set the in effect flag */
		temp_downtime->is_in_effect = TRUE;

		/* update the status data */
		if(temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* schedule an event to end the downtime */
		if(temp_downtime->fixed == FALSE) {
			event_time = (time_t)((unsigned long)temp_downtime->flex_downtime_start
					+ temp_downtime->duration);
			}
		else {
			event_time = temp_downtime->end_time;
			}
		if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = temp_downtime->downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
			}

		/* handle (start) downtime that is triggered by this one */
		for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
			if(this_downtime->triggered_by == temp_downtime->downtime_id)
				handle_scheduled_downtime(this_downtime);
			}
		}

	return OK;
	}
Ejemplo n.º 11
0
/* registers scheduled downtime (schedules it, adds comments, etc.) */
int register_downtime(int type, unsigned long downtime_id) {
	char *temp_buffer = NULL;
	char start_time_string[MAX_DATETIME_LENGTH] = "";
	char flex_start_string[MAX_DATETIME_LENGTH] = "";
	char end_time_string[MAX_DATETIME_LENGTH] = "";
	scheduled_downtime *temp_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	const char *type_string = NULL;
	int hours = 0;
	int minutes = 0;
	int seconds = 0;
	unsigned long *new_downtime_id = NULL;
	int was_in_effect = FALSE;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "register_downtime( %d, %lu)\n", type,
			downtime_id);

	/* find the downtime entry in memory */
	temp_downtime = find_downtime(type, downtime_id);
	if(temp_downtime == NULL) {
		log_debug_info(DEBUGL_DOWNTIME, 0, "Cannot find downtime ID: %lu\n", downtime_id);
		return ERROR;
		}

	/* find the host or service associated with this downtime */
	if(temp_downtime->type == HOST_DOWNTIME) {
		if((hst = find_host(temp_downtime->host_name)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Cannot find host (%s) for downtime ID: %lu\n",
					temp_downtime->host_name, downtime_id);
			return ERROR;
			}
		}
	else {
		if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Cannot find service (%s) for host (%s) for downtime ID: %lu\n",
					temp_downtime->service_description, temp_downtime->host_name,
					downtime_id);
			return ERROR;
			}
		}

	/* create the comment */
	get_datetime_string(&(temp_downtime->start_time), start_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->flex_downtime_start), flex_start_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->end_time), end_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	hours = temp_downtime->duration / 3600;
	minutes = ((temp_downtime->duration - (hours * 3600)) / 60);
	seconds = temp_downtime->duration - (hours * 3600) - (minutes * 60);
	if(temp_downtime->type == HOST_DOWNTIME)
		type_string = "host";
	else
		type_string = "service";
	if(temp_downtime->fixed == TRUE)
		asprintf(&temp_buffer, "This %s has been scheduled for fixed downtime from %s to %s.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, type_string);
	else
		asprintf(&temp_buffer, "This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, hours, minutes, type_string);


	log_debug_info(DEBUGL_DOWNTIME, 0, "Scheduled Downtime Details:\n");
	if(temp_downtime->type == HOST_DOWNTIME) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Host Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", hst->name);
		}
	else {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Service Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", svc->host_name);
		log_debug_info(DEBUGL_DOWNTIME, 0, " Service:     %s\n", svc->description);
		}
	log_debug_info(DEBUGL_DOWNTIME, 0, " Fixed/Flex:  %s\n", (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible");
	log_debug_info(DEBUGL_DOWNTIME, 0, " Start:       %s\n", start_time_string);
	if( temp_downtime->flex_downtime_start) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Flex Start:  %s\n", flex_start_string);
		}
	log_debug_info(DEBUGL_DOWNTIME, 0, " End:         %s\n", end_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Duration:    %dh %dm %ds\n", hours, minutes, seconds);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Downtime ID: %lu\n", temp_downtime->downtime_id);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Trigger ID:  %lu\n", temp_downtime->triggered_by);


	/* add a non-persistent comment to the host or service regarding the scheduled outage */
	if(temp_downtime->type == SERVICE_DOWNTIME)
		add_new_comment(SERVICE_COMMENT, DOWNTIME_COMMENT, svc->host_name, svc->description, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));
	else
		add_new_comment(HOST_COMMENT, DOWNTIME_COMMENT, hst->name, NULL, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));

	my_free(temp_buffer);

	/* only non-triggered downtime is scheduled... */
	if((temp_downtime->triggered_by == 0) && ((TRUE == temp_downtime->fixed) ||
			((FALSE == temp_downtime->fixed) &&
			(TRUE == temp_downtime->is_in_effect)))) {
		/* If this is a fixed downtime, schedule the event to start it. If this
			is a flexible downtime, normally we wait for one of the
			check_pending_flex_*_downtime() functions to start it, but if the
			downtime is already in effect, this means that we are restarting
			Nagios and the downtime was in effect when we last shutdown
			Nagios, so we should restart the flexible downtime now. This
			should work even if the downtime has ended because the
			handle_scheduled_dowtime() function will immediately schedule
			another downtime event which will end the downtime. */
		if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = downtime_id;
			temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
			/* Turn off is_in_effect flag so handle_scheduled_downtime() will
				handle it correctly */
			was_in_effect = temp_downtime->is_in_effect;
			temp_downtime->is_in_effect = FALSE;
			}
		}

	/* If the downtime is triggered and was in effect, mark it as not in 
		effect so it gets scheduled correctly */
	if((temp_downtime->triggered_by != 0) && 
			(TRUE == temp_downtime->is_in_effect)) {
		was_in_effect = temp_downtime->is_in_effect;
		temp_downtime->is_in_effect = FALSE;
		}

	if((FALSE == temp_downtime->fixed) && (FALSE == was_in_effect)) {
		/* increment pending flex downtime counter */
		if(temp_downtime->type == HOST_DOWNTIME)
			hst->pending_flex_downtime++;
		else
			svc->pending_flex_downtime++;
		temp_downtime->incremented_pending_downtime = TRUE;

		/* Since a flex downtime may never start, schedule an expiring event in
			case the event is never triggered. The expire event will NOT cancel
			a downtime event that is in effect */
		log_debug_info(DEBUGL_DOWNTIME, 1, "Scheduling downtime expire event in case flexible downtime is never triggered\n");
		temp_downtime->stop_event = schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0);
		}

#ifdef PROBABLY_NOT_NEEDED
	/*** FLEXIBLE DOWNTIME SANITY CHECK - ADDED 02/17/2008 ****/

	/* if host/service is in a non-OK/UP state right now, see if we should start flexible time immediately */
	/* this is new logic added in 3.0rc3 */
	if(temp_downtime->fixed == FALSE) {
		if(temp_downtime->type == HOST_DOWNTIME)
			check_pending_flex_host_downtime(hst);
		else
			check_pending_flex_service_downtime(svc);
		}
#endif

	return OK;
	}
Ejemplo n.º 12
0
int handle_startup(int which, void * obj) {
	struct nebstruct_process_struct *ps = (struct nebstruct_process_struct *)obj;
	time_t now = ps->timestamp.tv_sec;

	switch(ps->type) {
		case NEBTYPE_PROCESS_START:
			if(daemon_mode && !sigrestart)
				return 0;
		case NEBTYPE_PROCESS_DAEMONIZE: {
			json_t * pubdef = NULL, *pulldef = NULL, *reqdef = NULL;
			int numthreads = 1;

			if(get_values(config,
				"iothreads", JSON_INTEGER, 0, &numthreads,
				"publish", JSON_OBJECT, 0, &pubdef,
				"pull", JSON_OBJECT, 0, &pulldef,
				"reply", JSON_OBJECT, 0, &reqdef,
				NULL) != 0) {
				syslog(LOG_ERR, "Parameter error while starting NagMQ");
				return -1;
			}
		
			if(!pubdef && !pulldef && !reqdef)
				return 0;
			
			zmq_ctx = zmq_init(numthreads);
			if(zmq_ctx == NULL) {
				syslog(LOG_ERR, "Error initialzing ZMQ: %s",
					zmq_strerror(errno));
				return -1;
			}

			if(pubdef && handle_pubstartup(pubdef) < 0)
				return -1;

			if(pulldef) {
				unsigned long interval = 2;
				get_values(pulldef,
					"interval", JSON_INTEGER, 0, &interval,
					NULL);
				if((pullsock = getsock("pull", ZMQ_PULL, pulldef)) == NULL)
					return -1;
				schedule_new_event(EVENT_USER_FUNCTION, 1, now, 1, interval,
					NULL, 1, input_reaper, pullsock, 0);
			}

			if(reqdef) {
				unsigned long interval = 2;
				get_values(reqdef,
					"interval", JSON_INTEGER, 0, &interval,
					NULL);
				if((reqsock = getsock("reply", ZMQ_REP, reqdef)) == NULL)
					return -1;
				schedule_new_event(EVENT_USER_FUNCTION, 1, now, 1, interval,
					NULL, 1, input_reaper, reqsock, 0);
			}

			if(pulldef || reqdef)
				neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, handle, 0, handle_timedevent);
			break;
		}
		case NEBTYPE_PROCESS_SHUTDOWN:
		case NEBTYPE_PROCESS_RESTART:
			if(pullsock)
				zmq_close(pullsock);
			if(reqsock)
				zmq_close(reqsock);
			if(pubext)
				zmq_close(pubext);
			zmq_term(zmq_ctx);
			break;
		case NEBTYPE_PROCESS_EVENTLOOPSTART:
		case NEBTYPE_PROCESS_EVENTLOOPEND:
			if(pubext) {
				struct payload * payload;
				payload = payload_new();
				switch(ps->type) {
					case NEBTYPE_PROCESS_EVENTLOOPSTART:
						payload_new_string(payload, "type", "eventloopstart");
						break;
					case NEBTYPE_PROCESS_EVENTLOOPEND:
						payload_new_string(payload, "type", "eventloopend");
						break;
				}
				payload_new_timestamp(payload, "timestamp", &ps->timestamp);
				payload_finalize(payload);
				process_payload(payload);
			}
			break;
	}
	return 0;
}