Tip: If you want to have the option of getting the availability data in CSV format, select '
' from the pull-down menu.\n");
}
/* step 2 - the user wants to select a servicegroup */
else if(select_servicegroups == TRUE) {
printf("
\n");
}
/* step 2 - the user wants to select a service */
else if(select_services == TRUE) {
printf("\n");
printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '
** ALL SERVICES ** ' from the pull-down menu.\n");
}
/* generate availability report */
else if(display_type != DISPLAY_NO_AVAIL) {
/* check authorization */
is_authorized = TRUE;
if((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE)) {
if(display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE)
is_authorized = is_authorized_for_host(find_host(host_name), ¤t_authdata);
else
is_authorized = is_authorized_for_service(find_service(host_name, svc_description), ¤t_authdata);
}
if(is_authorized == FALSE)
printf("
It appears as though you are not authorized to view information for the specified %s...
\n", (display_type == DISPLAY_HOST_AVAIL) ? "host" : "service");
else {
time(&report_start_time);
/* create list of subjects to collect availability data for */
create_subject_list();
/* read in all necessary archived state data */
read_archived_state_data();
/* compute availability data */
compute_availability();
time(&report_end_time);
if(output_format == HTML_OUTPUT) {
get_time_breakdown((time_t)(report_end_time - report_start_time), &days, &hours, &minutes, &seconds);
printf("
[ Availability report completed in %d min %d sec ]
\n", minutes, seconds);
printf("
\n");
}
/* display availability data */
if(display_type == DISPLAY_HOST_AVAIL)
display_host_availability();
else if(display_type == DISPLAY_SERVICE_AVAIL)
display_service_availability();
else if(display_type == DISPLAY_HOSTGROUP_AVAIL)
display_hostgroup_availability();
else if(display_type == DISPLAY_SERVICEGROUP_AVAIL)
display_servicegroup_availability();
/* free memory allocated to availability data */
free_availability_data();
}
}
/* step 1 - ask the user what kind of report they want */
else {
printf("
Step 1: Select Report Type
\n");
printf("
\n");
printf("
\n");
printf("
\n");
}
document_footer();
/* free all other allocated memory */
free_memory();
return OK;
}
void document_header(int use_stylesheet) {
char date_time[MAX_DATETIME_LENGTH];
time_t current_time;
time_t expire_time;
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
time(¤t_time);
get_time_string(¤t_time, date_time, sizeof(date_time), HTTP_DATE_TIME);
printf("Last-Modified: %s\r\n", date_time);
expire_time = (time_t)0;
get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME);
printf("Expires: %s\r\n", date_time);
if(output_format == HTML_OUTPUT)
printf("Content-type: text/html\r\n\r\n");
else {
printf("Content-type: text/csv\r\n\r\n");
return;
}
if(embedded == TRUE || output_format == CSV_OUTPUT)
return;
printf("\n");
printf("\n");
printf("
\n", url_images_path);
printf("
\n");
printf("Nagios Availability\n");
printf(" \n");
if(use_stylesheet == TRUE) {
printf("
\n", url_stylesheets_path, COMMON_CSS);
printf("
\n", url_stylesheets_path, AVAIL_CSS);
}
printf("\n");
printf("\n");
/* include user SSI header */
include_ssi_files(AVAIL_CGI, SSI_HEADER);
return;
}
void document_footer(void) {
if(output_format != HTML_OUTPUT)
return;
if(embedded == TRUE)
return;
/* include user SSI footer */
include_ssi_files(AVAIL_CGI, SSI_FOOTER);
printf("\n");
printf("\n");
return;
}
int process_cgivars(void) {
char **variables;
int error = FALSE;
int x;
variables = getcgivars();
for(x = 0; variables[x] != NULL; x++) {
/* do some basic length checking on the variable identifier to prevent buffer overflows */
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
x++;
continue;
}
/* we found the hostgroup argument */
else if(!strcmp(variables[x], "hostgroup")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((hostgroup_name = (char *)strdup(variables[x])) == NULL)
hostgroup_name = "";
strip_html_brackets(hostgroup_name);
display_type = DISPLAY_HOSTGROUP_AVAIL;
show_all_hostgroups = (strcmp(hostgroup_name, "all")) ? FALSE : TRUE;
}
/* we found the servicegroup argument */
else if(!strcmp(variables[x], "servicegroup")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((servicegroup_name = (char *)strdup(variables[x])) == NULL)
servicegroup_name = "";
strip_html_brackets(servicegroup_name);
display_type = DISPLAY_SERVICEGROUP_AVAIL;
show_all_servicegroups = (strcmp(servicegroup_name, "all")) ? FALSE : TRUE;
}
/* we found the host argument */
else if(!strcmp(variables[x], "host")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((host_name = (char *)strdup(variables[x])) == NULL)
host_name = "";
strip_html_brackets(host_name);
display_type = DISPLAY_HOST_AVAIL;
show_all_hosts = (strcmp(host_name, "all")) ? FALSE : TRUE;
}
/* we found the service description argument */
else if(!strcmp(variables[x], "service")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((svc_description = (char *)strdup(variables[x])) == NULL)
svc_description = "";
strip_html_brackets(svc_description);
display_type = DISPLAY_SERVICE_AVAIL;
show_all_services = (strcmp(svc_description, "all")) ? FALSE : TRUE;
}
/* we found first time argument */
else if(!strcmp(variables[x], "t1")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
t1 = (time_t)strtoul(variables[x], NULL, 10);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = FALSE;
}
/* we found first time argument */
else if(!strcmp(variables[x], "t2")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
t2 = (time_t)strtoul(variables[x], NULL, 10);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = FALSE;
}
/* we found the assume initial states option */
else if(!strcmp(variables[x], "assumeinitialstates")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
assume_initial_states = TRUE;
else
assume_initial_states = FALSE;
}
/* we found the assume state during program not running option */
else if(!strcmp(variables[x], "assumestatesduringnotrunning")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
assume_states_during_notrunning = TRUE;
else
assume_states_during_notrunning = FALSE;
}
/* we found the initial assumed host state option */
else if(!strcmp(variables[x], "initialassumedhoststate")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
initial_assumed_host_state = atoi(variables[x]);
}
/* we found the initial assumed service state option */
else if(!strcmp(variables[x], "initialassumedservicestate")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
initial_assumed_service_state = atoi(variables[x]);
}
/* we found the assume state retention option */
else if(!strcmp(variables[x], "assumestateretention")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
assume_state_retention = TRUE;
else
assume_state_retention = FALSE;
}
/* we found the include soft states option */
else if(!strcmp(variables[x], "includesoftstates")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
include_soft_states = TRUE;
else
include_soft_states = FALSE;
}
/* we found the backtrack archives argument */
else if(!strcmp(variables[x], "backtrack")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
backtrack_archives = atoi(variables[x]);
if(backtrack_archives < 0)
backtrack_archives = 0;
if(backtrack_archives > MAX_ARCHIVE_BACKTRACKS)
backtrack_archives = MAX_ARCHIVE_BACKTRACKS;
#ifdef DEBUG
printf("BACKTRACK ARCHIVES: %d\n", backtrack_archives);
#endif
}
/* we found the standard timeperiod argument */
else if(!strcmp(variables[x], "timeperiod")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "today"))
timeperiod_type = TIMEPERIOD_TODAY;
else if(!strcmp(variables[x], "yesterday"))
timeperiod_type = TIMEPERIOD_YESTERDAY;
else if(!strcmp(variables[x], "thisweek"))
timeperiod_type = TIMEPERIOD_THISWEEK;
else if(!strcmp(variables[x], "lastweek"))
timeperiod_type = TIMEPERIOD_LASTWEEK;
else if(!strcmp(variables[x], "thismonth"))
timeperiod_type = TIMEPERIOD_THISMONTH;
else if(!strcmp(variables[x], "lastmonth"))
timeperiod_type = TIMEPERIOD_LASTMONTH;
else if(!strcmp(variables[x], "thisquarter"))
timeperiod_type = TIMEPERIOD_THISQUARTER;
else if(!strcmp(variables[x], "lastquarter"))
timeperiod_type = TIMEPERIOD_LASTQUARTER;
else if(!strcmp(variables[x], "thisyear"))
timeperiod_type = TIMEPERIOD_THISYEAR;
else if(!strcmp(variables[x], "lastyear"))
timeperiod_type = TIMEPERIOD_LASTYEAR;
else if(!strcmp(variables[x], "last24hours"))
timeperiod_type = TIMEPERIOD_LAST24HOURS;
else if(!strcmp(variables[x], "last7days"))
timeperiod_type = TIMEPERIOD_LAST7DAYS;
else if(!strcmp(variables[x], "last31days"))
timeperiod_type = TIMEPERIOD_LAST31DAYS;
else if(!strcmp(variables[x], "custom"))
timeperiod_type = TIMEPERIOD_CUSTOM;
else
continue;
convert_timeperiod_to_times(timeperiod_type);
compute_time_from_parts = FALSE;
}
/* we found the embed option */
else if(!strcmp(variables[x], "embedded"))
embedded = TRUE;
/* we found the noheader option */
else if(!strcmp(variables[x], "noheader"))
display_header = FALSE;
/* we found the CSV output option */
else if(!strcmp(variables[x], "csvoutput")) {
display_header = FALSE;
output_format = CSV_OUTPUT;
}
/* we found the log entries option */
else if(!strcmp(variables[x], "show_log_entries"))
show_log_entries = TRUE;
/* we found the full log entries option */
else if(!strcmp(variables[x], "full_log_entries"))
full_log_entries = TRUE;
/* we found the get date parts option */
else if(!strcmp(variables[x], "get_date_parts"))
get_date_parts = TRUE;
/* we found the report type selection option */
else if(!strcmp(variables[x], "report_type")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "hostgroups"))
select_hostgroups = TRUE;
else if(!strcmp(variables[x], "servicegroups"))
select_servicegroups = TRUE;
else if(!strcmp(variables[x], "hosts"))
select_hosts = TRUE;
else
select_services = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "smon")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
start_month = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "sday")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
start_day = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "syear")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
start_year = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "smin")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
start_minute = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "ssec")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
start_second = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "shour")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
start_hour = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "emon")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
end_month = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "eday")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
end_day = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "eyear")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
end_year = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "emin")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
end_minute = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "esec")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
end_second = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x], "ehour")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(timeperiod_type != TIMEPERIOD_CUSTOM)
continue;
end_hour = atoi(variables[x]);
timeperiod_type = TIMEPERIOD_CUSTOM;
compute_time_from_parts = TRUE;
}
/* we found the show scheduled downtime option */
else if(!strcmp(variables[x], "showscheduleddowntime")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
show_scheduled_downtime = TRUE;
else
show_scheduled_downtime = FALSE;
}
/* we found the report timeperiod option */
else if(!strcmp(variables[x], "rpttimeperiod")) {
timeperiod *temp_timeperiod;
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
for(temp_timeperiod = timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) {
if(!strcmp(url_encode(temp_timeperiod->name), variables[x])) {
current_timeperiod = temp_timeperiod;
break;
}
}
}
}
/* free memory allocated to the CGI variables */
free_cgivars(variables);
return error;
}
/* computes availability data for all subjects */
void compute_availability(void) {
avail_subject *temp_subject;
time_t current_time;
time(¤t_time);
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
compute_subject_availability(temp_subject, current_time);
compute_subject_downtime(temp_subject, current_time);
}
return;
}
/* computes availability data for a given subject */
void compute_subject_availability(avail_subject *subject, time_t current_time) {
archived_state *temp_as;
archived_state *last_as;
time_t a;
time_t b;
int current_state = AS_NO_DATA;
int have_some_real_data = FALSE;
hoststatus *hststatus = NULL;
servicestatus *svcstatus = NULL;
int first_real_state = AS_NO_DATA;
time_t initial_assumed_time;
int initial_assumed_state = AS_NO_DATA;
int error;
/* if left hand of graph is after current time, we can't do anything at all.... */
if(t1 > current_time)
return;
/* get current state of host or service if possible */
if(subject->type == HOST_SUBJECT)
hststatus = find_hoststatus(subject->host_name);
else
svcstatus = find_servicestatus(subject->host_name, subject->service_description);
/************************************/
/* INSERT CURRENT STATE (IF WE CAN) */
/************************************/
/* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */
/* if we don't have any data, assume current state (if possible) */
if(subject->as_list == NULL && current_time > t1 && current_time <= t2) {
/* we don't have any historical information, but the current time falls within the reporting period, so use */
/* the current status of the host/service as the starting data */
if(subject->type == HOST_SUBJECT) {
if(hststatus != NULL) {
if(hststatus->status == HOST_DOWN)
subject->last_known_state = AS_HOST_DOWN;
else if(hststatus->status == HOST_UNREACHABLE)
subject->last_known_state = AS_HOST_UNREACHABLE;
else if(hststatus->status == HOST_UP)
subject->last_known_state = AS_HOST_UP;
else
subject->last_known_state = AS_NO_DATA;
if(subject->last_known_state != AS_NO_DATA) {
/* add a dummy archived state item, so something can get graphed */
add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Host State Assumed (Faked Log Entry)", subject);
/* use the current state as the last known real state */
first_real_state = subject->last_known_state;
}
}
}
else {
if(svcstatus != NULL) {
if(svcstatus->status == SERVICE_OK)
subject->last_known_state = AS_SVC_OK;
else if(svcstatus->status == SERVICE_WARNING)
subject->last_known_state = AS_SVC_WARNING;
else if(svcstatus->status == SERVICE_CRITICAL)
subject->last_known_state = AS_SVC_CRITICAL;
else if(svcstatus->status == SERVICE_UNKNOWN)
subject->last_known_state = AS_SVC_UNKNOWN;
else
subject->last_known_state = AS_NO_DATA;
if(subject->last_known_state != AS_NO_DATA) {
/* add a dummy archived state item, so something can get graphed */
add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Service State Assumed (Faked Log Entry)", subject);
/* use the current state as the last known real state */
first_real_state = subject->last_known_state;
}
}
}
}
/******************************************/
/* INSERT FIRST ASSUMED STATE (IF WE CAN) */
/******************************************/
if((subject->type == HOST_SUBJECT && initial_assumed_host_state != AS_NO_DATA) || (subject->type == SERVICE_SUBJECT && initial_assumed_service_state != AS_NO_DATA)) {
/* see if its okay to assume initial state for this subject */
error = FALSE;
if(subject->type == SERVICE_SUBJECT) {
if(initial_assumed_service_state != AS_SVC_OK && initial_assumed_service_state != AS_SVC_WARNING && initial_assumed_service_state != AS_SVC_UNKNOWN && initial_assumed_service_state != AS_SVC_CRITICAL && initial_assumed_service_state != AS_CURRENT_STATE)
error = TRUE;
else
initial_assumed_state = initial_assumed_service_state;
if(initial_assumed_service_state == AS_CURRENT_STATE && svcstatus == NULL)
error = TRUE;
}
else {
if(initial_assumed_host_state != AS_HOST_UP && initial_assumed_host_state != AS_HOST_DOWN && initial_assumed_host_state != AS_HOST_UNREACHABLE && initial_assumed_host_state != AS_CURRENT_STATE)
error = TRUE;
else
initial_assumed_state = initial_assumed_host_state;
if(initial_assumed_host_state == AS_CURRENT_STATE && hststatus == NULL)
error = TRUE;
}
/* get the current state if applicable */
if(((subject->type == HOST_SUBJECT && initial_assumed_host_state == AS_CURRENT_STATE) || (subject->type == SERVICE_SUBJECT && initial_assumed_service_state == AS_CURRENT_STATE)) && error == FALSE) {
if(subject->type == SERVICE_SUBJECT) {
switch(svcstatus->status) {
case SERVICE_OK:
initial_assumed_state = AS_SVC_OK;
break;
case SERVICE_WARNING:
initial_assumed_state = AS_SVC_WARNING;
break;
case SERVICE_UNKNOWN:
initial_assumed_state = AS_SVC_UNKNOWN;
break;
case SERVICE_CRITICAL:
initial_assumed_state = AS_SVC_CRITICAL;
break;
default:
error = TRUE;
break;
}
}
else {
switch(hststatus->status) {
case HOST_DOWN:
initial_assumed_state = AS_HOST_DOWN;
break;
case HOST_UNREACHABLE:
initial_assumed_state = AS_HOST_UNREACHABLE;
break;
case HOST_UP:
initial_assumed_state = AS_HOST_UP;
break;
default:
error = TRUE;
break;
}
}
}
if(error == FALSE) {
/* add this assumed state entry before any entries in the list and <= t1 */
if(subject->as_list == NULL)
initial_assumed_time = t1;
else if(subject->as_list->time_stamp > t1)
initial_assumed_time = t1;
else
initial_assumed_time = subject->as_list->time_stamp - 1;
if(subject->type == HOST_SUBJECT)
add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Host State Assumed (Faked Log Entry)", subject);
else
add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Service State Assumed (Faked Log Entry)", subject);
}
}
/**************************************/
/* BAIL OUT IF WE DON'T HAVE ANYTHING */
/**************************************/
have_some_real_data = FALSE;
for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
if(temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_START && temp_as->entry_type != AS_PROGRAM_END) {
have_some_real_data = TRUE;
break;
}
}
if(have_some_real_data == FALSE)
return;
last_as = NULL;
subject->earliest_time = t2;
subject->latest_time = t1;
#ifdef DEBUG
printf("--- BEGINNING/MIDDLE SECTION ---
\n");
#endif
/**********************************/
/* BEGINNING/MIDDLE SECTION */
/**********************************/
for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
/* keep this as last known state if this is the first entry or if it occurs before the starting point of the graph */
if((temp_as->time_stamp <= t1 || temp_as == subject->as_list) && (temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_END && temp_as->entry_type != AS_PROGRAM_START)) {
subject->last_known_state = temp_as->entry_type;
#ifdef DEBUG
printf("SETTING LAST KNOWN STATE=%d
\n", subject->last_known_state);
#endif
}
/* skip this entry if it occurs before the starting point of the graph */
if(temp_as->time_stamp <= t1) {
#ifdef DEBUG
printf("SKIPPING PRE-EVENT: %d @ %lu
\n", temp_as->entry_type, temp_as->time_stamp);
#endif
last_as = temp_as;
continue;
}
/* graph this span if we're not on the first item */
if(last_as != NULL) {
a = last_as->time_stamp;
b = temp_as->time_stamp;
/* we've already passed the last time displayed in the graph */
if(a > t2)
break;
/* only graph this data if its on the graph */
else if(b > t1) {
/* clip last time if it exceeds graph limits */
if(b > t2)
b = t2;
/* clip first time if it precedes graph limits */
if(a < t1)
a = t1;
/* save this time if its the earliest we've graphed */
if(a < subject->earliest_time) {
subject->earliest_time = a;
subject->earliest_state = last_as->entry_type;
}
/* save this time if its the latest we've graphed */
if(b > subject->latest_time) {
subject->latest_time = b;
subject->latest_state = last_as->entry_type;
}
/* compute availability times for this chunk */
compute_subject_availability_times(last_as->entry_type, temp_as->entry_type, last_as->time_stamp, a, b, subject, temp_as);
/* return if we've reached the end of the graph limits */
if(b >= t2) {
last_as = temp_as;
break;
}
}
}
/* keep track of the last item */
last_as = temp_as;
}
#ifdef DEBUG
printf("--- END SECTION ---
\n");
#endif
/**********************************/
/* END SECTION */
/**********************************/
if(last_as != NULL) {
/* don't process an entry that is beyond the limits of the graph */
if(last_as->time_stamp < t2) {
time(¤t_time);
b = current_time;
if(b > t2)
b = t2;
a = last_as->time_stamp;
if(a < t1)
a = t1;
/* fake the current state (it doesn't really matter for graphing) */
if(subject->type == HOST_SUBJECT)
current_state = AS_HOST_UP;
else
current_state = AS_SVC_OK;
/* compute availability times for last state */
compute_subject_availability_times(last_as->entry_type, current_state, last_as->time_stamp, a, b, subject, last_as);
}
}
return;
}
/* computes availability times */
void compute_subject_availability_times(int first_state, int last_state, time_t real_start_time, time_t start_time, time_t end_time, avail_subject *subject, archived_state *as) {
int start_state;
int end_state;
unsigned long state_duration;
struct tm *t;
unsigned long midnight_today;
int weekday;
timerange *temp_timerange;
unsigned long temp_duration;
unsigned long temp_end;
unsigned long temp_start;
unsigned long start;
unsigned long end;
#ifdef DEBUG
if(subject->type == HOST_SUBJECT)
printf("HOST '%s'...\n", subject->host_name);
else
printf("SERVICE '%s' ON HOST '%s'...\n", subject->service_description, subject->host_name);
printf("COMPUTING %d->%d FROM %lu to %lu (%lu seconds) FOR %s
\n", first_state, last_state, start_time, end_time, (end_time - start_time), (subject->type == HOST_SUBJECT) ? "HOST" : "SERVICE");
#endif
/* clip times if necessary */
if(start_time < t1)
start_time = t1;
if(end_time > t2)
end_time = t2;
/* make sure this is a valid time */
if(start_time > t2)
return;
if(end_time < t1)
return;
/* MickeM - attempt to handle the current time_period (if any) */
if(current_timeperiod != NULL) {
t = localtime((time_t *)&start_time);
state_duration = 0;
/* calculate the start of the day (midnight, 00:00 hours) */
t->tm_sec = 0;
t->tm_min = 0;
t->tm_hour = 0;
t->tm_isdst = -1;
midnight_today = (unsigned long)mktime(t);
weekday = t->tm_wday;
while(midnight_today < end_time) {
temp_duration = 0;
temp_end = min(86400, end_time - midnight_today);
temp_start = 0;
if(start_time > midnight_today)
temp_start = start_time - midnight_today;
#ifdef DEBUG
printf("
Matching: %ld -> %ld. (%ld -> %ld) \n", temp_start, temp_end, midnight_today + temp_start, midnight_today + temp_end);
#endif
/* check all time ranges for this day of the week */
for(temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) {
#ifdef DEBUG
printf("
Matching in timerange[%d]: %d -> %d (%ld -> %ld) \n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end);
#endif
start = max(temp_timerange->range_start, temp_start);
end = min(temp_timerange->range_end, temp_end);
if(start < end) {
temp_duration += end - start;
#ifdef DEBUG
printf(" Matched time: %ld -> %ld = %d \n", start, end, temp_duration);
#endif
}
#ifdef DEBUG
else
printf(" Ignored time: %ld -> %ld \n", start, end);
#endif
}
state_duration += temp_duration;
temp_start = 0;
midnight_today += 86400;
if(++weekday > 6)
weekday = 0;
}
}
/* no report timeperiod was selected (assume 24x7) */
else {
/* calculate time in this state */
state_duration = (unsigned long)(end_time - start_time);
}
/* can't graph if we don't have data... */
if(first_state == AS_NO_DATA || last_state == AS_NO_DATA) {
subject->time_indeterminate_nodata += state_duration;
return;
}
if(first_state == AS_PROGRAM_START && (last_state == AS_PROGRAM_END || last_state == AS_PROGRAM_START)) {
if(assume_initial_states == FALSE) {
subject->time_indeterminate_nodata += state_duration;
return;
}
}
if(first_state == AS_PROGRAM_END) {
/* added 7/24/03 */
if(assume_states_during_notrunning == TRUE) {
first_state = subject->last_known_state;
}
else {
subject->time_indeterminate_notrunning += state_duration;
return;
}
}
/* special case if first entry was program start */
if(first_state == AS_PROGRAM_START) {
if(assume_initial_states == TRUE) {
if(assume_state_retention == TRUE)
start_state = subject->last_known_state;
else {
if(subject->type == HOST_SUBJECT)
start_state = AS_HOST_UP;
else
start_state = AS_SVC_OK;
}
}
else
return;
}
else {
start_state = first_state;
subject->last_known_state = first_state;
}
/* special case if last entry was program stop */
if(last_state == AS_PROGRAM_END)
end_state = first_state;
else
end_state = last_state;
/* save "processed state" info */
as->processed_state = start_state;
#ifdef DEBUG
printf("PASSED TIME CHECKS, CLIPPED VALUES: START=%lu, END=%lu\n", start_time, end_time);
#endif
/* add time in this state to running totals */
switch(start_state) {
case AS_HOST_UP:
subject->time_up += state_duration;
break;
case AS_HOST_DOWN:
subject->time_down += state_duration;
break;
case AS_HOST_UNREACHABLE:
subject->time_unreachable += state_duration;
break;
case AS_SVC_OK:
subject->time_ok += state_duration;
break;
case AS_SVC_WARNING:
subject->time_warning += state_duration;
break;
case AS_SVC_UNKNOWN:
subject->time_unknown += state_duration;
break;
case AS_SVC_CRITICAL:
subject->time_critical += state_duration;
break;
default:
break;
}
return;
}
/* computes downtime data for a given subject */
void compute_subject_downtime(avail_subject *subject, time_t current_time) {
archived_state *temp_sd;
time_t start_time;
time_t end_time;
int host_downtime_depth = 0;
int service_downtime_depth = 0;
int process_chunk = FALSE;
#ifdef DEBUG2
printf("COMPUTE_SUBJECT_DOWNTIME\n");
#endif
/* if left hand of graph is after current time, we can't do anything at all.... */
if(t1 > current_time)
return;
/* no scheduled downtime data for subject... */
if(subject->sd_list == NULL)
return;
/* all data we have occurs after last time on graph... */
if(subject->sd_list->time_stamp >= t2)
return;
/* initialize pointer */
temp_sd = subject->sd_list;
/* special case if first entry is the end of scheduled downtime */
if((temp_sd->entry_type == AS_HOST_DOWNTIME_END || temp_sd->entry_type == AS_SVC_DOWNTIME_END) && temp_sd->time_stamp > t1) {
#ifdef DEBUG2
printf("\tSPECIAL DOWNTIME CASE\n");
#endif
start_time = t1;
end_time = (temp_sd->time_stamp > t2) ? t2 : temp_sd->time_stamp;
compute_subject_downtime_times(start_time, end_time, subject, NULL);
temp_sd = temp_sd->next;
}
/* process all periods of scheduled downtime */
for(; temp_sd != NULL; temp_sd = temp_sd->next) {
/* we've passed graph bounds... */
if(temp_sd->time_stamp >= t2)
break;
if(temp_sd->entry_type == AS_HOST_DOWNTIME_START)
host_downtime_depth++;
else if(temp_sd->entry_type == AS_HOST_DOWNTIME_END)
host_downtime_depth--;
else if(temp_sd->entry_type == AS_SVC_DOWNTIME_START)
service_downtime_depth++;
else if(temp_sd->entry_type == AS_SVC_DOWNTIME_END)
service_downtime_depth--;
else
continue;
process_chunk = FALSE;
if(temp_sd->entry_type == AS_HOST_DOWNTIME_START || temp_sd->entry_type == AS_SVC_DOWNTIME_START)
process_chunk = TRUE;
else if(subject->type == SERVICE_SUBJECT && (host_downtime_depth > 0 || service_downtime_depth > 0))
process_chunk = TRUE;
/* process this specific "chunk" of scheduled downtime */
if(process_chunk == TRUE) {
start_time = temp_sd->time_stamp;
end_time = (temp_sd->next == NULL) ? current_time : temp_sd->next->time_stamp;
/* check time sanity */
if(end_time <= t1)
continue;
if(start_time >= t2)
continue;
if(start_time >= end_time)
continue;
/* clip time values */
if(start_time < t1)
start_time = t1;
if(end_time > t2)
end_time = t2;
compute_subject_downtime_times(start_time, end_time, subject, temp_sd);
}
}
return;
}
/* computes downtime times */
void compute_subject_downtime_times(time_t start_time, time_t end_time, avail_subject *subject, archived_state *sd) {
archived_state *temp_as = NULL;
time_t part_start_time = 0L;
time_t part_subject_state = 0L;
int saved_status = 0;
int saved_stamp = 0;
int count = 0;
archived_state *temp_before = NULL;
archived_state *last = NULL;
#ifdef DEBUG2
printf("ENTERING COMPUTE_SUBJECT_DOWNTIME_TIMES: start=%lu, end=%lu, t1=%lu, t2=%lu
", start_time, end_time, t1, t2);
#endif
/* times are weird, so bail out... */
if(start_time > end_time)
return;
if(start_time < t1 || end_time > t2)
return;
/* find starting point in archived state list */
if(sd == NULL) {
#ifdef DEBUG2
printf("TEMP_AS=SUBJECT->AS_LIST
");
#endif
temp_as = subject->as_list;
}
else if(sd->misc_ptr == NULL) {
#ifdef DEBUG2
printf("TEMP_AS=SUBJECT->AS_LIST
");
#endif
temp_as = subject->as_list;
}
else if(sd->misc_ptr->next == NULL) {
#ifdef DEBUG2
printf("TEMP_AS=SD->MISC_PTR
");
#endif
temp_as = sd->misc_ptr;
}
else {
#ifdef DEBUG2
printf("TEMP_AS=SD->MISC_PTR->NEXT
");
#endif
temp_as = sd->misc_ptr->next;
}
/* initialize values */
part_start_time = start_time;
if(temp_as == NULL)
part_subject_state = AS_NO_DATA;
else if(temp_as->processed_state == AS_PROGRAM_START || temp_as->processed_state == AS_PROGRAM_END || temp_as->processed_state == AS_NO_DATA) {
#ifdef DEBUG2
printf("ENTRY TYPE #1: %d
", temp_as->entry_type);
#endif
part_subject_state = AS_NO_DATA;
}
else {
#ifdef DEBUG2
printf("ENTRY TYPE #2: %d
", temp_as->entry_type);
#endif
part_subject_state = temp_as->processed_state;
}
#ifdef DEBUG2
printf("TEMP_AS=%s
", (temp_as == NULL) ? "NULL" : "Not NULL");
printf("SD=%s
", (sd == NULL) ? "NULL" : "Not NULL");
#endif
/* temp_as now points to first event to possibly "break" this chunk */
for(; temp_as != NULL; temp_as = temp_as->next) {
count++;
last = temp_as;
if(temp_before == NULL) {
if(last->time_stamp > start_time) {
if(last->time_stamp > end_time)
compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject);
else
compute_subject_downtime_part_times(start_time, last->time_stamp, part_subject_state, subject);
}
temp_before = temp_as;
saved_status = temp_as->entry_type;
saved_stamp = temp_as->time_stamp;
/* check if first time is before schedule downtime */
if(saved_stamp < start_time)
saved_stamp = start_time;
continue;
}
/* if status changed, we have to calculate */
if(saved_status != temp_as->entry_type) {
/* is outside schedule time, use end schdule downtime */
if(temp_as->time_stamp > end_time) {
if(saved_stamp < start_time)
compute_subject_downtime_part_times(start_time, end_time, saved_status, subject);
else
compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject);
}
else {
if(saved_stamp < start_time)
compute_subject_downtime_part_times(start_time, temp_as->time_stamp, saved_status, subject);
else
compute_subject_downtime_part_times(saved_stamp, temp_as->time_stamp, saved_status, subject);
}
saved_status = temp_as->entry_type;
saved_stamp = temp_as->time_stamp;
}
}
/* just one entry inside the scheduled downtime */
if(count == 0)
compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject);
else {
/* is outside scheduled time, use end schdule downtime */
if(last->time_stamp > end_time)
compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject);
else
compute_subject_downtime_part_times(saved_stamp, last->time_stamp, saved_status, subject);
}
return;
}
/* computes downtime times */
void compute_subject_downtime_part_times(time_t start_time, time_t end_time, int subject_state, avail_subject *subject) {
unsigned long state_duration;
#ifdef DEBUG2
printf("ENTERING COMPUTE_SUBJECT_DOWNTIME_PART_TIMES\n");
#endif
/* times are weird */
if(start_time > end_time)
return;
state_duration = (unsigned long)(end_time - start_time);
switch(subject_state) {
case AS_HOST_UP:
subject->scheduled_time_up += state_duration;
break;
case AS_HOST_DOWN:
subject->scheduled_time_down += state_duration;
break;
case AS_HOST_UNREACHABLE:
subject->scheduled_time_unreachable += state_duration;
break;
case AS_SVC_OK:
subject->scheduled_time_ok += state_duration;
break;
case AS_SVC_WARNING:
subject->scheduled_time_warning += state_duration;
break;
case AS_SVC_UNKNOWN:
subject->scheduled_time_unknown += state_duration;
break;
case AS_SVC_CRITICAL:
subject->scheduled_time_critical += state_duration;
break;
default:
subject->scheduled_time_indeterminate += state_duration;
break;
}
#ifdef DEBUG2
printf("\tSUBJECT DOWNTIME: Host '%s', Service '%s', State=%d, Duration=%lu, Start=%lu\n", subject->host_name, (subject->service_description == NULL) ? "NULL" : subject->service_description, subject_state, state_duration, start_time);
#endif
return;
}
/* convert current host state to archived state value */
int convert_host_state_to_archived_state(int current_status) {
if(current_status == HOST_UP)
return AS_HOST_UP;
if(current_status == HOST_DOWN)
return AS_HOST_DOWN;
if(current_status == HOST_UNREACHABLE)
return AS_HOST_UNREACHABLE;
return AS_NO_DATA;
}
/* convert current service state to archived state value */
int convert_service_state_to_archived_state(int current_status) {
if(current_status == SERVICE_OK)
return AS_SVC_OK;
if(current_status == SERVICE_UNKNOWN)
return AS_SVC_UNKNOWN;
if(current_status == SERVICE_WARNING)
return AS_SVC_WARNING;
if(current_status == SERVICE_CRITICAL)
return AS_SVC_CRITICAL;
return AS_NO_DATA;
}
/* create list of subjects to collect availability data for */
void create_subject_list(void) {
hostgroup *temp_hostgroup;
hostsmember *temp_hgmember;
servicegroup *temp_servicegroup;
servicesmember *temp_sgmember;
host *temp_host;
service *temp_service;
char *last_host_name = "";
/* we're displaying one or more hosts */
if(display_type == DISPLAY_HOST_AVAIL && host_name && strcmp(host_name, "")) {
/* we're only displaying a specific host (and summaries for all services associated with it) */
if(show_all_hosts == FALSE) {
add_subject(HOST_SUBJECT, host_name, NULL);
for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
if(!strcmp(temp_service->host_name, host_name))
add_subject(SERVICE_SUBJECT, host_name, temp_service->description);
}
}
/* we're displaying all hosts */
else {
for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next)
add_subject(HOST_SUBJECT, temp_host->name, NULL);
}
}
/* we're displaying a specific service */
else if(display_type == DISPLAY_SERVICE_AVAIL && svc_description && strcmp(svc_description, "")) {
/* we're only displaying a specific service */
if(show_all_services == FALSE)
add_subject(SERVICE_SUBJECT, host_name, svc_description);
/* we're displaying all services */
else {
for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next)
add_subject(SERVICE_SUBJECT, temp_service->host_name, temp_service->description);
}
}
/* we're displaying one or more hostgroups (the host members of the groups) */
else if(display_type == DISPLAY_HOSTGROUP_AVAIL && hostgroup_name && strcmp(hostgroup_name, "")) {
/* we're displaying all hostgroups */
if(show_all_hostgroups == TRUE) {
for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next)
add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL);
}
}
/* we're only displaying a specific hostgroup */
else {
temp_hostgroup = find_hostgroup(hostgroup_name);
if(temp_hostgroup != NULL) {
for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next)
add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL);
}
}
}
/* we're displaying one or more servicegroups (the host and service members of the groups) */
else if(display_type == DISPLAY_SERVICEGROUP_AVAIL && servicegroup_name && strcmp(servicegroup_name, "")) {
/* we're displaying all servicegroups */
if(show_all_servicegroups == TRUE) {
for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) {
add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description);
if(strcmp(last_host_name, temp_sgmember->host_name))
add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL);
last_host_name = temp_sgmember->host_name;
}
}
}
/* we're only displaying a specific servicegroup */
else {
temp_servicegroup = find_servicegroup(servicegroup_name);
if(temp_servicegroup != NULL) {
for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) {
add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description);
if(strcmp(last_host_name, temp_sgmember->host_name))
add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL);
last_host_name = temp_sgmember->host_name;
}
}
}
}
return;
}
/* adds a subject */
void add_subject(int subject_type, char *hn, char *sd) {
avail_subject *last_subject = NULL;
avail_subject *temp_subject = NULL;
avail_subject *new_subject = NULL;
int is_authorized = FALSE;
/* bail if we've already added the subject */
if(find_subject(subject_type, hn, sd))
return;
/* see if the user is authorized to see data for this host or service */
if(subject_type == HOST_SUBJECT)
is_authorized = is_authorized_for_host(find_host(hn), ¤t_authdata);
else
is_authorized = is_authorized_for_service(find_service(hn, sd), ¤t_authdata);
if(is_authorized == FALSE)
return;
/* allocate memory for the new entry */
new_subject = (avail_subject *)malloc(sizeof(avail_subject));
if(new_subject == NULL)
return;
/* allocate memory for the host name */
if(hn != NULL) {
new_subject->host_name = (char *)malloc(strlen(hn) + 1);
if(new_subject->host_name != NULL)
strcpy(new_subject->host_name, hn);
}
else
new_subject->host_name = NULL;
/* allocate memory for the service description */
if(sd != NULL) {
new_subject->service_description = (char *)malloc(strlen(sd) + 1);
if(new_subject->service_description != NULL)
strcpy(new_subject->service_description, sd);
}
else
new_subject->service_description = NULL;
new_subject->type = subject_type;
new_subject->earliest_state = AS_NO_DATA;
new_subject->latest_state = AS_NO_DATA;
new_subject->time_up = 0L;
new_subject->time_down = 0L;
new_subject->time_unreachable = 0L;
new_subject->time_ok = 0L;
new_subject->time_warning = 0L;
new_subject->time_unknown = 0L;
new_subject->time_critical = 0L;
new_subject->scheduled_time_up = 0L;
new_subject->scheduled_time_down = 0L;
new_subject->scheduled_time_unreachable = 0L;
new_subject->scheduled_time_ok = 0L;
new_subject->scheduled_time_warning = 0L;
new_subject->scheduled_time_unknown = 0L;
new_subject->scheduled_time_critical = 0L;
new_subject->scheduled_time_indeterminate = 0L;
new_subject->time_indeterminate_nodata = 0L;
new_subject->time_indeterminate_notrunning = 0L;
new_subject->as_list = NULL;
new_subject->as_list_tail = NULL;
new_subject->sd_list = NULL;
new_subject->last_known_state = AS_NO_DATA;
/* add the new entry to the list in memory, sorted by host name */
last_subject = subject_list;
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(strcmp(new_subject->host_name, temp_subject->host_name) < 0) {
new_subject->next = temp_subject;
if(temp_subject == subject_list)
subject_list = new_subject;
else
last_subject->next = new_subject;
break;
}
else
last_subject = temp_subject;
}
if(subject_list == NULL) {
new_subject->next = NULL;
subject_list = new_subject;
}
else if(temp_subject == NULL) {
new_subject->next = NULL;
last_subject->next = new_subject;
}
return;
}
/* finds a specific subject */
avail_subject *find_subject(int type, char *hn, char *sd) {
avail_subject *temp_subject;
if(hn == NULL)
return NULL;
if(type == SERVICE_SUBJECT && sd == NULL)
return NULL;
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != type)
continue;
if(strcmp(hn, temp_subject->host_name))
continue;
if(type == SERVICE_SUBJECT && strcmp(sd, temp_subject->service_description))
continue;
return temp_subject;
}
return NULL;
}
/* adds an archived state entry to all subjects */
void add_global_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info) {
avail_subject *temp_subject;
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next)
add_archived_state(entry_type, state_type, time_stamp, state_info, temp_subject);
return;
}
/* adds an archived state entry to a specific subject */
void add_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info, avail_subject *subject) {
archived_state *last_as = NULL;
archived_state *temp_as = NULL;
archived_state *new_as = NULL;
/* allocate memory for the new entry */
new_as = (archived_state *)malloc(sizeof(archived_state));
if(new_as == NULL)
return;
/* allocate memory for the state info */
if(state_info != NULL) {
new_as->state_info = (char *)malloc(strlen(state_info) + 1);
if(new_as->state_info != NULL)
strcpy(new_as->state_info, state_info);
}
else new_as->state_info = NULL;
/* initialize the "processed state" value - this gets modified later for most entries */
if(entry_type != AS_PROGRAM_START && entry_type != AS_PROGRAM_END && entry_type != AS_NO_DATA)
new_as->processed_state = entry_type;
else
new_as->processed_state = AS_NO_DATA;
new_as->entry_type = entry_type;
new_as->state_type = state_type;
new_as->time_stamp = time_stamp;
new_as->misc_ptr = NULL;
/* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */
last_as = subject->as_list;
for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
if(new_as->time_stamp < temp_as->time_stamp) {
new_as->next = temp_as;
if(temp_as == subject->as_list)
subject->as_list = new_as;
else
last_as->next = new_as;
break;
}
else
last_as = temp_as;
}
if(subject->as_list == NULL) {
new_as->next = NULL;
subject->as_list = new_as;
}
else if(temp_as == NULL) {
new_as->next = NULL;
last_as->next = new_as;
}
/* update "tail" of the list - not really the tail, just last item added */
subject->as_list_tail = new_as;
return;
}
/* adds a scheduled downtime entry to a specific subject */
void add_scheduled_downtime(int state_type, time_t time_stamp, avail_subject *subject) {
archived_state *last_sd = NULL;
archived_state *temp_sd = NULL;
archived_state *new_sd = NULL;
/* allocate memory for the new entry */
new_sd = (archived_state *)malloc(sizeof(archived_state));
if(new_sd == NULL)
return;
new_sd->state_info = NULL;
new_sd->processed_state = state_type;
new_sd->entry_type = state_type;
new_sd->time_stamp = time_stamp;
new_sd->misc_ptr = subject->as_list_tail;
/* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */
last_sd = subject->sd_list;
for(temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) {
if(new_sd->time_stamp <= temp_sd->time_stamp) {
new_sd->next = temp_sd;
if(temp_sd == subject->sd_list)
subject->sd_list = new_sd;
else
last_sd->next = new_sd;
break;
}
else
last_sd = temp_sd;
}
if(subject->sd_list == NULL) {
new_sd->next = NULL;
subject->sd_list = new_sd;
}
else if(temp_sd == NULL) {
new_sd->next = NULL;
last_sd->next = new_sd;
}
return;
}
/* frees memory allocated to all availability data */
void free_availability_data(void) {
avail_subject *this_subject;
avail_subject *next_subject;
for(this_subject = subject_list; this_subject != NULL;) {
next_subject = this_subject->next;
if(this_subject->host_name != NULL)
free(this_subject->host_name);
if(this_subject->service_description != NULL)
free(this_subject->service_description);
free_archived_state_list(this_subject->as_list);
free_archived_state_list(this_subject->sd_list);
free(this_subject);
this_subject = next_subject;
}
return;
}
/* frees memory allocated to the archived state list */
void free_archived_state_list(archived_state *as_list) {
archived_state *this_as = NULL;
archived_state *next_as = NULL;
for(this_as = as_list; this_as != NULL;) {
next_as = this_as->next;
if(this_as->state_info != NULL)
free(this_as->state_info);
free(this_as);
this_as = next_as;
}
as_list = NULL;
return;
}
/* reads log files for archived state data */
void read_archived_state_data(void) {
char filename[MAX_FILENAME_LENGTH];
int oldest_archive = 0;
int newest_archive = 0;
int current_archive = 0;
/* determine oldest archive to use when scanning for data (include backtracked archives as well) */
oldest_archive = determine_archive_to_use_from_time(t1);
if(log_rotation_method != LOG_ROTATION_NONE)
oldest_archive += backtrack_archives;
/* determine most recent archive to use when scanning for data */
newest_archive = determine_archive_to_use_from_time(t2);
if(oldest_archive < newest_archive)
oldest_archive = newest_archive;
/* read in all the necessary archived logs (from most recent to earliest) */
for(current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) {
#ifdef DEBUG
printf("Reading archive #%d\n", current_archive);
#endif
/* get the name of the log file that contains this archive */
get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1);
#ifdef DEBUG
printf("Archive name: '%s'\n", filename);
#endif
/* scan the log file for archived state data */
scan_log_file_for_archived_state_data(filename);
}
return;
}
/* grabs archives state data from a log file */
void scan_log_file_for_archived_state_data(char *filename) {
char *input = NULL;
char *input2 = NULL;
char entry_host_name[MAX_INPUT_BUFFER];
char entry_svc_description[MAX_INPUT_BUFFER];
char *plugin_output = NULL;
char *temp_buffer = NULL;
time_t time_stamp;
mmapfile *thefile = NULL;
avail_subject *temp_subject = NULL;
int state_type = 0;
if((thefile = mmap_fopen(filename)) == NULL)
return;
while(1) {
/* free memory */
free(input);
free(input2);
input = NULL;
input2 = NULL;
/* read the next line */
if((input = mmap_fgets(thefile)) == NULL)
break;
strip(input);
if((input2 = strdup(input)) == NULL)
continue;
temp_buffer = my_strtok(input2, "]");
time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10);
/* program starts/restarts */
if(strstr(input, " starting..."))
add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program start");
if(strstr(input, " restarting..."))
add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program restart");
/* program stops */
if(strstr(input, " shutting down..."))
add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Normal program termination");
if(strstr(input, "Bailing out"))
add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Abnormal program termination");
if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) {
/* normal host alerts and initial/current states */
if(strstr(input, "HOST ALERT:") || strstr(input, "INITIAL HOST STATE:") || strstr(input, "CURRENT HOST STATE:")) {
/* get host name */
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
/* see if there is a corresponding subject for this host */
temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL);
if(temp_subject == NULL)
continue;
/* state types */
if(strstr(input, ";SOFT;")) {
if(include_soft_states == FALSE)
continue;
state_type = AS_SOFT_STATE;
}
if(strstr(input, ";HARD;"))
state_type = AS_HARD_STATE;
/* get the plugin output */
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
plugin_output = my_strtok(NULL, "\n");
if(strstr(input, ";DOWN;"))
add_archived_state(AS_HOST_DOWN, state_type, time_stamp, plugin_output, temp_subject);
else if(strstr(input, ";UNREACHABLE;"))
add_archived_state(AS_HOST_UNREACHABLE, state_type, time_stamp, plugin_output, temp_subject);
else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;"))
add_archived_state(AS_HOST_UP, state_type, time_stamp, plugin_output, temp_subject);
else
add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject);
}
/* scheduled downtime notices */
else if(strstr(input, "HOST DOWNTIME ALERT:")) {
/* get host name */
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
/* see if there is a corresponding subject for this host */
temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL);
if(temp_subject == NULL)
continue;
if(show_scheduled_downtime == FALSE)
continue;
if(strstr(input, ";STARTED;"))
add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject);
else
add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject);
}
}
if(display_type == DISPLAY_SERVICE_AVAIL || display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) {
/* normal service alerts and initial/current states */
if(strstr(input, "SERVICE ALERT:") || strstr(input, "INITIAL SERVICE STATE:") || strstr(input, "CURRENT SERVICE STATE:")) {
/* get host name */
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
/* get service description */
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description));
entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0';
/* see if there is a corresponding subject for this service */
temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description);
if(temp_subject == NULL)
continue;
/* state types */
if(strstr(input, ";SOFT;")) {
if(include_soft_states == FALSE)
continue;
state_type = AS_SOFT_STATE;
}
if(strstr(input, ";HARD;"))
state_type = AS_HARD_STATE;
/* get the plugin output */
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
plugin_output = my_strtok(NULL, "\n");
if(strstr(input, ";CRITICAL;"))
add_archived_state(AS_SVC_CRITICAL, state_type, time_stamp, plugin_output, temp_subject);
else if(strstr(input, ";WARNING;"))
add_archived_state(AS_SVC_WARNING, state_type, time_stamp, plugin_output, temp_subject);
else if(strstr(input, ";UNKNOWN;"))
add_archived_state(AS_SVC_UNKNOWN, state_type, time_stamp, plugin_output, temp_subject);
else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;"))
add_archived_state(AS_SVC_OK, state_type, time_stamp, plugin_output, temp_subject);
else
add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject);
}
/* scheduled service downtime notices */
else if(strstr(input, "SERVICE DOWNTIME ALERT:")) {
/* get host name */
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
/* get service description */
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description));
entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0';
/* see if there is a corresponding subject for this service */
temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description);
if(temp_subject == NULL)
continue;
if(show_scheduled_downtime == FALSE)
continue;
if(strstr(input, ";STARTED;"))
add_scheduled_downtime(AS_SVC_DOWNTIME_START, time_stamp, temp_subject);
else
add_scheduled_downtime(AS_SVC_DOWNTIME_END, time_stamp, temp_subject);
}
/* scheduled host downtime notices */
else if(strstr(input, "HOST DOWNTIME ALERT:")) {
/* get host name */
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
/* this host downtime entry must be added to all service subjects associated with the host! */
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != SERVICE_SUBJECT)
continue;
if(strcmp(temp_subject->host_name, entry_host_name))
continue;
if(show_scheduled_downtime == FALSE)
continue;
if(strstr(input, ";STARTED;"))
add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject);
else
add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject);
}
}
}
}
/* free memory and close the file */
free(input);
free(input2);
mmap_fclose(thefile);
return;
}
void convert_timeperiod_to_times(int type) {
time_t current_time;
struct tm *t;
/* get the current time */
time(¤t_time);
t = localtime(¤t_time);
t->tm_sec = 0;
t->tm_min = 0;
t->tm_hour = 0;
t->tm_isdst = -1;
switch(type) {
case TIMEPERIOD_LAST24HOURS:
t1 = current_time - (60 * 60 * 24);
t2 = current_time;
break;
case TIMEPERIOD_TODAY:
t1 = mktime(t);
t2 = current_time;
break;
case TIMEPERIOD_YESTERDAY:
t1 = (time_t)(mktime(t) - (60 * 60 * 24));
t2 = (time_t)mktime(t);
break;
case TIMEPERIOD_THISWEEK:
t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday));
t2 = current_time;
break;
case TIMEPERIOD_LASTWEEK:
t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7));
t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday));
break;
case TIMEPERIOD_THISMONTH:
t->tm_mday = 1;
t1 = mktime(t);
t2 = current_time;
break;
case TIMEPERIOD_LASTMONTH:
t->tm_mday = 1;
t2 = mktime(t);
if(t->tm_mon == 0) {
t->tm_mon = 11;
t->tm_year--;
}
else
t->tm_mon--;
t1 = mktime(t);
break;
case TIMEPERIOD_THISQUARTER:
/* not implemented */
break;
case TIMEPERIOD_LASTQUARTER:
/* not implemented */
break;
case TIMEPERIOD_THISYEAR:
t->tm_mon = 0;
t->tm_mday = 1;
t1 = mktime(t);
t2 = current_time;
break;
case TIMEPERIOD_LASTYEAR:
t->tm_mon = 0;
t->tm_mday = 1;
t2 = mktime(t);
t->tm_year--;
t1 = mktime(t);
break;
case TIMEPERIOD_LAST7DAYS:
t2 = current_time;
t1 = current_time - (7 * 24 * 60 * 60);
break;
case TIMEPERIOD_LAST31DAYS:
t2 = current_time;
t1 = current_time - (31 * 24 * 60 * 60);
break;
default:
break;
}
return;
}
void compute_report_times(void) {
time_t current_time;
struct tm *st;
struct tm *et;
/* get the current time */
time(¤t_time);
st = localtime(¤t_time);
st->tm_sec = start_second;
st->tm_min = start_minute;
st->tm_hour = start_hour;
st->tm_mday = start_day;
st->tm_mon = start_month - 1;
st->tm_year = start_year - 1900;
st->tm_isdst = -1;
t1 = mktime(st);
et = localtime(¤t_time);
et->tm_sec = end_second;
et->tm_min = end_minute;
et->tm_hour = end_hour;
et->tm_mday = end_day;
et->tm_mon = end_month - 1;
et->tm_year = end_year - 1900;
et->tm_isdst = -1;
t2 = mktime(et);
}
/* writes log entries to screen */
void write_log_entries(avail_subject *subject) {
archived_state *temp_as;
archived_state *temp_sd;
time_t current_time;
char start_date_time[MAX_DATETIME_LENGTH];
char end_date_time[MAX_DATETIME_LENGTH];
char duration[20];
char *bgclass = "";
char *ebgclass = "";
char *entry_type = "";
char *state_type = "";
int days;
int hours;
int minutes;
int seconds;
int odd = 0;
if(output_format != HTML_OUTPUT)
return;
if(show_log_entries == FALSE)
return;
if(subject == NULL)
return;
time(¤t_time);
/* inject all scheduled downtime entries into the main list for display purposes */
for(temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) {
switch(temp_sd->entry_type) {
case AS_SVC_DOWNTIME_START:
case AS_HOST_DOWNTIME_START:
entry_type = "Start of scheduled downtime";
break;
case AS_SVC_DOWNTIME_END:
case AS_HOST_DOWNTIME_END:
entry_type = "End of scheduled downtime";
break;
default:
entry_type = "?";
break;
}
add_archived_state(temp_sd->entry_type, AS_NO_DATA, temp_sd->time_stamp, entry_type, subject);
}
printf(" \n");
printf("%s Log Entries:
\n", (subject->type == HOST_SUBJECT) ? "Host" : "Service");
printf("");
if(full_log_entries == TRUE) {
full_log_entries = FALSE;
if(subject->type == HOST_SUBJECT)
host_report_url(subject->host_name, "[ View condensed log entries ]");
else
service_report_url(subject->host_name, subject->service_description, "[ View condensed log entries ]");
full_log_entries = TRUE;
}
else {
full_log_entries = TRUE;
if(subject->type == HOST_SUBJECT)
host_report_url(subject->host_name, "[ View full log entries ]");
else
service_report_url(subject->host_name, subject->service_description, "[ View full log entries ]");
full_log_entries = FALSE;
}
printf("
\n");
printf("\n");
printf("
\n");
printf("Event Start Time Event End Time Event Duration Event/State Type Event/State Information \n");
/* write all archived state entries */
for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
if(temp_as->state_type == AS_HARD_STATE)
state_type = " (HARD)";
else if(temp_as->state_type == AS_SOFT_STATE)
state_type = " (SOFT)";
else
state_type = "";
switch(temp_as->entry_type) {
case AS_NO_DATA:
if(full_log_entries == FALSE)
continue;
entry_type = "NO DATA";
ebgclass = "INDETERMINATE";
break;
case AS_PROGRAM_END:
if(full_log_entries == FALSE)
continue;
entry_type = "PROGRAM END";
ebgclass = "INDETERMINATE";
break;
case AS_PROGRAM_START:
if(full_log_entries == FALSE)
continue;
entry_type = "PROGRAM (RE)START";
ebgclass = "INDETERMINATE";
break;
case AS_HOST_UP:
entry_type = "HOST UP";
ebgclass = "UP";
break;
case AS_HOST_DOWN:
entry_type = "HOST DOWN";
ebgclass = "DOWN";
break;
case AS_HOST_UNREACHABLE:
entry_type = "HOST UNREACHABLE";
ebgclass = "UNREACHABLE";
break;
case AS_SVC_OK:
entry_type = "SERVICE OK";
ebgclass = "OK";
break;
case AS_SVC_UNKNOWN:
entry_type = "SERVICE UNKNOWN";
ebgclass = "UNKNOWN";
break;
case AS_SVC_WARNING:
entry_type = "SERVICE WARNING";
ebgclass = "WARNING";
break;
case AS_SVC_CRITICAL:
entry_type = "SERVICE CRITICAL";
ebgclass = "CRITICAL";
break;
case AS_SVC_DOWNTIME_START:
entry_type = "SERVICE DOWNTIME START";
ebgclass = "INDETERMINATE";
break;
case AS_SVC_DOWNTIME_END:
entry_type = "SERVICE DOWNTIME END";
ebgclass = "INDETERMINATE";
break;
case AS_HOST_DOWNTIME_START:
entry_type = "HOST DOWNTIME START";
ebgclass = "INDETERMINATE";
break;
case AS_HOST_DOWNTIME_END:
entry_type = "HOST DOWNTIME END";
ebgclass = "INDETERMINATE";
break;
default:
if(full_log_entries == FALSE)
continue;
entry_type = "?";
ebgclass = "INDETERMINATE";
}
get_time_string(&(temp_as->time_stamp), start_date_time, sizeof(start_date_time) - 1, SHORT_DATE_TIME);
if(temp_as->next == NULL) {
get_time_string(&t2, end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME);
get_time_breakdown((time_t)(t2 - temp_as->time_stamp), &days, &hours, &minutes, &seconds);
snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds+", days, hours, minutes, seconds);
}
else {
get_time_string(&(temp_as->next->time_stamp), end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME);
get_time_breakdown((time_t)(temp_as->next->time_stamp - temp_as->time_stamp), &days, &hours, &minutes, &seconds);
snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
}
if(odd) {
bgclass = "Odd";
odd = 0;
}
else {
bgclass = "Even";
odd = 1;
}
printf("", bgclass);
printf("%s ", bgclass, start_date_time);
printf("%s ", bgclass, end_date_time);
printf("%s ", bgclass, duration);
printf("%s%s ", ebgclass, entry_type, state_type);
printf("%s ", bgclass, (temp_as->state_info == NULL) ? "" : html_encode(temp_as->state_info, FALSE));
printf(" \n");
}
printf("
\n");
printf("
\n");
return;
}
/* display hostgroup availability */
void display_hostgroup_availability(void) {
hostgroup *temp_hostgroup;
/* display data for a specific hostgroup */
if(show_all_hostgroups == FALSE) {
temp_hostgroup = find_hostgroup(hostgroup_name);
display_specific_hostgroup_availability(temp_hostgroup);
}
/* display data for all hostgroups */
else {
for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next)
display_specific_hostgroup_availability(temp_hostgroup);
}
return;
}
/* display availability for a specific hostgroup */
void display_specific_hostgroup_availability(hostgroup *hg) {
unsigned long total_time;
unsigned long time_determinate;
unsigned long time_indeterminate;
avail_subject *temp_subject;
double percent_time_up = 0.0;
double percent_time_down = 0.0;
double percent_time_unreachable = 0.0;
double percent_time_up_known = 0.0;
double percent_time_down_known = 0.0;
double percent_time_unreachable_known = 0.0;
double percent_time_indeterminate = 0.0;
double average_percent_time_up = 0.0;
double average_percent_time_up_known = 0.0;
double average_percent_time_down = 0.0;
double average_percent_time_down_known = 0.0;
double average_percent_time_unreachable = 0.0;
double average_percent_time_unreachable_known = 0.0;
double average_percent_time_indeterminate = 0.0;
int current_subject = 0;
char *bgclass = "";
int odd = 1;
host *temp_host;
if(hg == NULL)
return;
/* the user isn't authorized to view this hostgroup */
if(is_authorized_for_hostgroup(hg, ¤t_authdata) == FALSE)
return;
/* calculate total time during period based on timeperiod used for reporting */
total_time = calculate_total_time(t1, t2);
printf(" \n");
printf("Hostgroup '%s' Host State Breakdowns:
\n", hg->group_name);
printf("\n");
printf("
\n");
printf("Host %% Time Up %% Time Down %% Time Unreachable %% Time Undetermined \n");
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != HOST_SUBJECT)
continue;
temp_host = find_host(temp_subject->host_name);
if(temp_host == NULL)
continue;
if(is_host_member_of_hostgroup(hg, temp_host) == FALSE)
continue;
current_subject++;
/* reset variables */
percent_time_up = 0.0;
percent_time_down = 0.0;
percent_time_unreachable = 0.0;
percent_time_indeterminate = 0.0;
percent_time_up_known = 0.0;
percent_time_down_known = 0.0;
percent_time_unreachable_known = 0.0;
time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
time_indeterminate = total_time - time_determinate;
if(total_time > 0) {
percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
}
}
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("", bgclass, bgclass);
host_report_url(temp_subject->host_name, temp_subject->host_name);
printf(" %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate);
get_running_average(&average_percent_time_up, percent_time_up, current_subject);
get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject);
get_running_average(&average_percent_time_down, percent_time_down, current_subject);
get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject);
get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject);
get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject);
get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
}
/* average statistics */
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("Average %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% ", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate);
printf("
\n");
printf("
\n");
return;
}
/* display servicegroup availability */
void display_servicegroup_availability(void) {
servicegroup *temp_servicegroup;
/* display data for a specific servicegroup */
if(show_all_servicegroups == FALSE) {
temp_servicegroup = find_servicegroup(servicegroup_name);
display_specific_servicegroup_availability(temp_servicegroup);
}
/* display data for all servicegroups */
else {
for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next)
display_specific_servicegroup_availability(temp_servicegroup);
}
return;
}
/* display availability for a specific servicegroup */
void display_specific_servicegroup_availability(servicegroup *sg) {
unsigned long total_time;
unsigned long time_determinate;
unsigned long time_indeterminate;
avail_subject *temp_subject;
double percent_time_up = 0.0;
double percent_time_down = 0.0;
double percent_time_unreachable = 0.0;
double percent_time_up_known = 0.0;
double percent_time_down_known = 0.0;
double percent_time_unreachable_known = 0.0;
double percent_time_indeterminate = 0.0;
double percent_time_ok = 0.0;
double percent_time_warning = 0.0;
double percent_time_unknown = 0.0;
double percent_time_critical = 0.0;
double percent_time_ok_known = 0.0;
double percent_time_warning_known = 0.0;
double percent_time_unknown_known = 0.0;
double percent_time_critical_known = 0.0;
double average_percent_time_up = 0.0;
double average_percent_time_up_known = 0.0;
double average_percent_time_down = 0.0;
double average_percent_time_down_known = 0.0;
double average_percent_time_unreachable = 0.0;
double average_percent_time_unreachable_known = 0.0;
double average_percent_time_ok = 0.0;
double average_percent_time_ok_known = 0.0;
double average_percent_time_unknown = 0.0;
double average_percent_time_unknown_known = 0.0;
double average_percent_time_warning = 0.0;
double average_percent_time_warning_known = 0.0;
double average_percent_time_critical = 0.0;
double average_percent_time_critical_known = 0.0;
double average_percent_time_indeterminate = 0.0;
int current_subject = 0;
char *bgclass = "";
int odd = 1;
host *temp_host;
service *temp_service;
char last_host[MAX_INPUT_BUFFER];
if(sg == NULL)
return;
/* the user isn't authorized to view this servicegroup */
if(is_authorized_for_servicegroup(sg, ¤t_authdata) == FALSE)
return;
/* calculate total time during period based on timeperiod used for reporting */
total_time = calculate_total_time(t1, t2);
printf(" \n");
printf("Servicegroup '%s' Host State Breakdowns:
\n", sg->group_name);
printf("\n");
printf("
\n");
printf("Host %% Time Up %% Time Down %% Time Unreachable %% Time Undetermined \n");
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != HOST_SUBJECT)
continue;
temp_host = find_host(temp_subject->host_name);
if(temp_host == NULL)
continue;
if(is_host_member_of_servicegroup(sg, temp_host) == FALSE)
continue;
current_subject++;
/* reset variables */
percent_time_up = 0.0;
percent_time_down = 0.0;
percent_time_unreachable = 0.0;
percent_time_indeterminate = 0.0;
percent_time_up_known = 0.0;
percent_time_down_known = 0.0;
percent_time_unreachable_known = 0.0;
time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
time_indeterminate = total_time - time_determinate;
if(total_time > 0) {
percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
}
}
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("", bgclass, bgclass);
host_report_url(temp_subject->host_name, temp_subject->host_name);
printf(" %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate);
get_running_average(&average_percent_time_up, percent_time_up, current_subject);
get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject);
get_running_average(&average_percent_time_down, percent_time_down, current_subject);
get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject);
get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject);
get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject);
get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
}
/* average statistics */
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("Average %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% ", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate);
printf("
\n");
printf("
\n");
printf(" \n");
printf("Servicegroup '%s' Service State Breakdowns:
\n", sg->group_name);
printf("\n");
printf("
\n");
printf("Host Service %% Time OK %% Time Warning %% Time Unknown %% Time Critical %% Time Undetermined \n");
current_subject = 0;
average_percent_time_indeterminate = 0.0;
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != SERVICE_SUBJECT)
continue;
temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
if(temp_service == NULL)
continue;
if(is_service_member_of_servicegroup(sg, temp_service) == FALSE)
continue;
current_subject++;
time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
time_indeterminate = total_time - time_determinate;
/* adjust indeterminate time due to insufficient data (not all was caught) */
temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
/* initialize values */
percent_time_ok = 0.0;
percent_time_warning = 0.0;
percent_time_unknown = 0.0;
percent_time_critical = 0.0;
percent_time_indeterminate = 0.0;
percent_time_ok_known = 0.0;
percent_time_warning_known = 0.0;
percent_time_unknown_known = 0.0;
percent_time_critical_known = 0.0;
if(total_time > 0) {
percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
}
}
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("", bgclass, bgclass);
if(strcmp(temp_subject->host_name, last_host))
host_report_url(temp_subject->host_name, temp_subject->host_name);
printf(" ", bgclass);
service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description);
printf(" %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate);
strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1);
last_host[sizeof(last_host) - 1] = '\x0';
get_running_average(&average_percent_time_ok, percent_time_ok, current_subject);
get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject);
get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject);
get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject);
get_running_average(&average_percent_time_warning, percent_time_warning, current_subject);
get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject);
get_running_average(&average_percent_time_critical, percent_time_critical, current_subject);
get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject);
get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
}
/* display average stats */
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("Average %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate);
printf("
\n");
printf("
\n");
return;
}
/* display host availability */
void display_host_availability(void) {
unsigned long total_time;
unsigned long time_determinate;
unsigned long time_indeterminate;
avail_subject *temp_subject;
host *temp_host;
service *temp_service;
int days, hours, minutes, seconds;
char time_indeterminate_string[48];
char time_determinate_string[48];
char total_time_string[48];
double percent_time_ok = 0.0;
double percent_time_warning = 0.0;
double percent_time_unknown = 0.0;
double percent_time_critical = 0.0;
double percent_time_indeterminate = 0.0;
double percent_time_ok_known = 0.0;
double percent_time_warning_known = 0.0;
double percent_time_unknown_known = 0.0;
double percent_time_critical_known = 0.0;
char time_up_string[48];
char time_down_string[48];
char time_unreachable_string[48];
double percent_time_up = 0.0;
double percent_time_down = 0.0;
double percent_time_unreachable = 0.0;
double percent_time_up_known = 0.0;
double percent_time_down_known = 0.0;
double percent_time_unreachable_known = 0.0;
double percent_time_up_scheduled = 0.0;
double percent_time_up_unscheduled = 0.0;
double percent_time_down_scheduled = 0.0;
double percent_time_down_unscheduled = 0.0;
double percent_time_unreachable_scheduled = 0.0;
double percent_time_unreachable_unscheduled = 0.0;
double percent_time_up_scheduled_known = 0.0;
double percent_time_up_unscheduled_known = 0.0;
double percent_time_down_scheduled_known = 0.0;
double percent_time_down_unscheduled_known = 0.0;
double percent_time_unreachable_scheduled_known = 0.0;
double percent_time_unreachable_unscheduled_known = 0.0;
char time_up_scheduled_string[48];
char time_up_unscheduled_string[48];
char time_down_scheduled_string[48];
char time_down_unscheduled_string[48];
char time_unreachable_scheduled_string[48];
char time_unreachable_unscheduled_string[48];
char time_indeterminate_scheduled_string[48];
char time_indeterminate_unscheduled_string[48];
double percent_time_indeterminate_scheduled = 0.0;
double percent_time_indeterminate_unscheduled = 0.0;
char time_indeterminate_notrunning_string[48];
char time_indeterminate_nodata_string[48];
double percent_time_indeterminate_notrunning = 0.0;
double percent_time_indeterminate_nodata = 0.0;
double average_percent_time_up = 0.0;
double average_percent_time_up_known = 0.0;
double average_percent_time_down = 0.0;
double average_percent_time_down_known = 0.0;
double average_percent_time_unreachable = 0.0;
double average_percent_time_unreachable_known = 0.0;
double average_percent_time_indeterminate = 0.0;
double average_percent_time_ok = 0.0;
double average_percent_time_ok_known = 0.0;
double average_percent_time_unknown = 0.0;
double average_percent_time_unknown_known = 0.0;
double average_percent_time_warning = 0.0;
double average_percent_time_warning_known = 0.0;
double average_percent_time_critical = 0.0;
double average_percent_time_critical_known = 0.0;
int current_subject = 0;
char *bgclass = "";
int odd = 1;
/* calculate total time during period based on timeperiod used for reporting */
total_time = calculate_total_time(t1, t2);
#ifdef DEBUG
printf("Total time: '%ld' seconds \n", total_time);
#endif
/* show data for a specific host */
if(show_all_hosts == FALSE) {
temp_subject = find_subject(HOST_SUBJECT, host_name, NULL);
if(temp_subject == NULL)
return;
temp_host = find_host(temp_subject->host_name);
if(temp_host == NULL)
return;
/* the user isn't authorized to view this host */
if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE)
return;
time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
time_indeterminate = total_time - time_determinate;
/* adjust indeterminate time due to insufficient data (not all was caught) */
temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
/* up times */
get_time_breakdown(temp_subject->time_up, &days, &hours, &minutes, &seconds);
snprintf(time_up_string, sizeof(time_up_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds);
snprintf(time_up_scheduled_string, sizeof(time_up_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_up - temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds);
snprintf(time_up_unscheduled_string, sizeof(time_up_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
/* down times */
get_time_breakdown(temp_subject->time_down, &days, &hours, &minutes, &seconds);
snprintf(time_down_string, sizeof(time_down_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds);
snprintf(time_down_scheduled_string, sizeof(time_down_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_down - temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds);
snprintf(time_down_unscheduled_string, sizeof(time_down_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
/* unreachable times */
get_time_breakdown(temp_subject->time_unreachable, &days, &hours, &minutes, &seconds);
snprintf(time_unreachable_string, sizeof(time_unreachable_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds);
snprintf(time_unreachable_scheduled_string, sizeof(time_unreachable_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds);
snprintf(time_unreachable_unscheduled_string, sizeof(time_unreachable_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
/* indeterminate times */
get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds);
snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(total_time, &days, &hours, &minutes, &seconds);
snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
if(total_time > 0) {
percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
percent_time_up_scheduled = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)total_time);
percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled;
percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
percent_time_down_scheduled = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)total_time);
percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled;
percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
percent_time_unreachable_scheduled = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)total_time);
percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled;
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
percent_time_up_scheduled_known = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)time_determinate);
percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known;
percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
percent_time_down_scheduled_known = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)time_determinate);
percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known;
percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
percent_time_unreachable_scheduled_known = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)time_determinate);
percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known;
}
}
printf("Host State Breakdowns:
\n");
#ifdef USE_TRENDS
printf("\n");
printf("", t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_host_state, backtrack_archives);
printf(" ", t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_host_state, backtrack_archives);
printf(" \n");
printf("
\n");
#endif
printf("\n");
printf("
\n");
printf("State Type / Reason Time %% Total Time %% Known Time \n");
/* up times */
printf("UP ");
printf("Unscheduled %s %2.3f%% %2.3f%% \n", time_up_unscheduled_string, percent_time_up, percent_time_up_known);
printf("Scheduled %s %2.3f%% %2.3f%% \n", time_up_scheduled_string, percent_time_up_scheduled, percent_time_up_scheduled_known);
printf("Total %s %2.3f%% %2.3f%% \n", time_up_string, percent_time_up, percent_time_up_known);
/* down times */
printf("DOWN ");
printf("Unscheduled %s %2.3f%% %2.3f%% \n", time_down_unscheduled_string, percent_time_down_unscheduled, percent_time_down_unscheduled_known);
printf("Scheduled %s %2.3f%% %2.3f%% \n", time_down_scheduled_string, percent_time_down_scheduled, percent_time_down_scheduled_known);
printf("Total %s %2.3f%% %2.3f%% \n", time_down_string, percent_time_down, percent_time_down_known);
/* unreachable times */
printf("UNREACHABLE ");
printf("Unscheduled %s %2.3f%% %2.3f%% \n", time_unreachable_unscheduled_string, percent_time_unreachable, percent_time_unreachable_known);
printf("Scheduled %s %2.3f%% %2.3f%% \n", time_unreachable_scheduled_string, percent_time_unreachable_scheduled, percent_time_unreachable_scheduled_known);
printf("Total %s %2.3f%% %2.3f%% \n", time_unreachable_string, percent_time_unreachable, percent_time_unreachable_known);
/* indeterminate times */
printf("Undetermined ");
printf("Nagios Not Running %s %2.3f%% \n", time_indeterminate_notrunning_string, percent_time_indeterminate_notrunning);
printf("Insufficient Data %s %2.3f%% \n", time_indeterminate_nodata_string, percent_time_indeterminate_nodata);
printf("Total %s %2.3f%% \n", time_indeterminate_string, percent_time_indeterminate);
printf(" \n");
printf("All Total %s 100.000%% 100.000%% \n", total_time_string);
printf("
\n");
printf("
\n");
/* display state breakdowns for all services on this host */
printf(" \n");
printf("State Breakdowns For Host Services:
\n");
printf("\n");
printf("
\n");
printf("Service %% Time OK %% Time Warning %% Time Unknown %% Time Critical %% Time Undetermined \n");
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != SERVICE_SUBJECT)
continue;
temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
if(temp_service == NULL)
continue;
/* the user isn't authorized to view this service */
if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
continue;
current_subject++;
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
/* reset variables */
percent_time_ok = 0.0;
percent_time_warning = 0.0;
percent_time_unknown = 0.0;
percent_time_critical = 0.0;
percent_time_indeterminate = 0.0;
percent_time_ok_known = 0.0;
percent_time_warning_known = 0.0;
percent_time_unknown_known = 0.0;
percent_time_critical_known = 0.0;
time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
time_indeterminate = total_time - time_determinate;
if(total_time > 0) {
percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
}
}
printf("", bgclass, bgclass);
service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description);
printf(" %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate);
get_running_average(&average_percent_time_ok, percent_time_ok, current_subject);
get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject);
get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject);
get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject);
get_running_average(&average_percent_time_warning, percent_time_warning, current_subject);
get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject);
get_running_average(&average_percent_time_critical, percent_time_critical, current_subject);
get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject);
get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
}
/* display average stats */
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("Average %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate);
printf("
\n");
printf("
\n");
/* write log entries for the host */
temp_subject = find_subject(HOST_SUBJECT, host_name, NULL);
write_log_entries(temp_subject);
}
/* display data for all hosts */
else {
if(output_format == HTML_OUTPUT) {
printf(" \n");
printf("Host State Breakdowns:
\n");
printf("\n");
printf("
\n");
printf("Host %% Time Up %% Time Down %% Time Unreachable %% Time Undetermined \n");
}
else if(output_format == CSV_OUTPUT) {
printf("HOST_NAME,");
printf(" TIME_UP_SCHEDULED, PERCENT_TIME_UP_SCHEDULED, PERCENT_KNOWN_TIME_UP_SCHEDULED, TIME_UP_UNSCHEDULED, PERCENT_TIME_UP_UNSCHEDULED, PERCENT_KNOWN_TIME_UP_UNSCHEDULED, TOTAL_TIME_UP, PERCENT_TOTAL_TIME_UP, PERCENT_KNOWN_TIME_UP,");
printf(" TIME_DOWN_SCHEDULED, PERCENT_TIME_DOWN_SCHEDULED, PERCENT_KNOWN_TIME_DOWN_SCHEDULED, TIME_DOWN_UNSCHEDULED, PERCENT_TIME_DOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_DOWN_UNSCHEDULED, TOTAL_TIME_DOWN, PERCENT_TOTAL_TIME_DOWN, PERCENT_KNOWN_TIME_DOWN,");
printf(" TIME_UNREACHABLE_SCHEDULED, PERCENT_TIME_UNREACHABLE_SCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_SCHEDULED, TIME_UNREACHABLE_UNSCHEDULED, PERCENT_TIME_UNREACHABLE_UNSCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_UNSCHEDULED, TOTAL_TIME_UNREACHABLE, PERCENT_TOTAL_TIME_UNREACHABLE, PERCENT_KNOWN_TIME_UNREACHABLE,");
printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n");
}
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != HOST_SUBJECT)
continue;
temp_host = find_host(temp_subject->host_name);
if(temp_host == NULL)
continue;
/* the user isn't authorized to view this host */
if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE)
continue;
current_subject++;
time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
time_indeterminate = total_time - time_determinate;
/* adjust indeterminate time due to insufficient data (not all was caught) */
temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
/* initialize values */
percent_time_up = 0.0;
percent_time_up_scheduled = 0.0;
percent_time_up_unscheduled = 0.0;
percent_time_down = 0.0;
percent_time_down_scheduled = 0.0;
percent_time_down_unscheduled = 0.0;
percent_time_unreachable = 0.0;
percent_time_unreachable_scheduled = 0.0;
percent_time_unreachable_unscheduled = 0.0;
percent_time_indeterminate = 0.0;
percent_time_indeterminate_scheduled = 0.0;
percent_time_indeterminate_unscheduled = 0.0;
percent_time_indeterminate_notrunning = 0.0;
percent_time_indeterminate_nodata = 0.0;
percent_time_up_known = 0.0;
percent_time_up_scheduled_known = 0.0;
percent_time_up_unscheduled_known = 0.0;
percent_time_down_known = 0.0;
percent_time_down_scheduled_known = 0.0;
percent_time_down_unscheduled_known = 0.0;
percent_time_unreachable_known = 0.0;
percent_time_unreachable_scheduled_known = 0.0;
percent_time_unreachable_unscheduled_known = 0.0;
if(total_time > 0) {
percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
percent_time_up_scheduled = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)total_time);
percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled;
percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
percent_time_down_scheduled = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)total_time);
percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled;
percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
percent_time_unreachable_scheduled = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)total_time);
percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled;
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
percent_time_up_scheduled_known = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)time_determinate);
percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known;
percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
percent_time_down_scheduled_known = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)time_determinate);
percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known;
percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
percent_time_unreachable_scheduled_known = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)time_determinate);
percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known;
}
}
if(output_format == HTML_OUTPUT) {
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("", bgclass, bgclass);
host_report_url(temp_subject->host_name, temp_subject->host_name);
printf(" %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate);
}
else if(output_format == CSV_OUTPUT) {
/* host name */
printf("\"%s\",", temp_subject->host_name);
/* up times */
printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_up, percent_time_up_scheduled, percent_time_up_scheduled_known, temp_subject->time_up - temp_subject->scheduled_time_up, percent_time_up_unscheduled, percent_time_up_unscheduled_known, temp_subject->time_up, percent_time_up, percent_time_up_known);
/* down times */
printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_down, percent_time_down_scheduled, percent_time_down_scheduled_known, temp_subject->time_down - temp_subject->scheduled_time_down, percent_time_down_unscheduled, percent_time_down_unscheduled_known, temp_subject->time_down, percent_time_down, percent_time_down_known);
/* unreachable times */
printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_unreachable, percent_time_unreachable_scheduled, percent_time_unreachable_scheduled_known, temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable, percent_time_unreachable_unscheduled, percent_time_unreachable_unscheduled_known, temp_subject->time_unreachable, percent_time_unreachable, percent_time_unreachable_known);
/* indeterminate times */
printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning, temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata, time_indeterminate, percent_time_indeterminate);
}
get_running_average(&average_percent_time_up, percent_time_up, current_subject);
get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject);
get_running_average(&average_percent_time_down, percent_time_down, current_subject);
get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject);
get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject);
get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject);
get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
}
if(output_format == HTML_OUTPUT) {
/* average statistics */
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("Average %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% ", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate);
printf("
\n");
printf("
\n");
}
}
return;
}
/* display service availability */
void display_service_availability(void) {
unsigned long total_time;
unsigned long time_determinate;
unsigned long time_indeterminate;
avail_subject *temp_subject;
service *temp_service;
int days, hours, minutes, seconds;
char time_ok_string[48];
char time_warning_string[48];
char time_unknown_string[48];
char time_critical_string[48];
char time_indeterminate_string[48];
char time_determinate_string[48];
char total_time_string[48];
double percent_time_ok = 0.0;
double percent_time_warning = 0.0;
double percent_time_unknown = 0.0;
double percent_time_critical = 0.0;
double percent_time_indeterminate = 0.0;
double percent_time_ok_known = 0.0;
double percent_time_warning_known = 0.0;
double percent_time_unknown_known = 0.0;
double percent_time_critical_known = 0.0;
char time_critical_scheduled_string[48];
char time_critical_unscheduled_string[48];
double percent_time_critical_scheduled = 0.0;
double percent_time_critical_unscheduled = 0.0;
double percent_time_critical_scheduled_known = 0.0;
double percent_time_critical_unscheduled_known = 0.0;
char time_unknown_scheduled_string[48];
char time_unknown_unscheduled_string[48];
double percent_time_unknown_scheduled = 0.0;
double percent_time_unknown_unscheduled = 0.0;
double percent_time_unknown_scheduled_known = 0.0;
double percent_time_unknown_unscheduled_known = 0.0;
char time_warning_scheduled_string[48];
char time_warning_unscheduled_string[48];
double percent_time_warning_scheduled = 0.0;
double percent_time_warning_unscheduled = 0.0;
double percent_time_warning_scheduled_known = 0.0;
double percent_time_warning_unscheduled_known = 0.0;
char time_ok_scheduled_string[48];
char time_ok_unscheduled_string[48];
double percent_time_ok_scheduled = 0.0;
double percent_time_ok_unscheduled = 0.0;
double percent_time_ok_scheduled_known = 0.0;
double percent_time_ok_unscheduled_known = 0.0;
double average_percent_time_ok = 0.0;
double average_percent_time_ok_known = 0.0;
double average_percent_time_unknown = 0.0;
double average_percent_time_unknown_known = 0.0;
double average_percent_time_warning = 0.0;
double average_percent_time_warning_known = 0.0;
double average_percent_time_critical = 0.0;
double average_percent_time_critical_known = 0.0;
double average_percent_time_indeterminate = 0.0;
int current_subject = 0;
char time_indeterminate_scheduled_string[48];
char time_indeterminate_unscheduled_string[48];
double percent_time_indeterminate_scheduled = 0.0;
double percent_time_indeterminate_unscheduled = 0.0;
char time_indeterminate_notrunning_string[48];
char time_indeterminate_nodata_string[48];
double percent_time_indeterminate_notrunning = 0.0;
double percent_time_indeterminate_nodata = 0.0;
int odd = 1;
char *bgclass = "";
char last_host[128] = "";
/* calculate total time during period based on timeperiod used for reporting */
total_time = calculate_total_time(t1, t2);
/* we're only getting data for one service */
if(show_all_services == FALSE) {
temp_subject = find_subject(SERVICE_SUBJECT, host_name, svc_description);
if(temp_subject == NULL)
return;
temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
if(temp_service == NULL)
return;
/* the user isn't authorized to view this service */
if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
return;
time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
time_indeterminate = total_time - time_determinate;
/* adjust indeterminate time due to insufficient data (not all was caught) */
temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
/* ok states */
get_time_breakdown(temp_subject->time_ok, &days, &hours, &minutes, &seconds);
snprintf(time_ok_string, sizeof(time_ok_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds);
snprintf(time_ok_scheduled_string, sizeof(time_ok_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_ok - temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds);
snprintf(time_ok_unscheduled_string, sizeof(time_ok_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
/* warning states */
get_time_breakdown(temp_subject->time_warning, &days, &hours, &minutes, &seconds);
snprintf(time_warning_string, sizeof(time_warning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds);
snprintf(time_warning_scheduled_string, sizeof(time_warning_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_warning - temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds);
snprintf(time_warning_unscheduled_string, sizeof(time_warning_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
/* unknown states */
get_time_breakdown(temp_subject->time_unknown, &days, &hours, &minutes, &seconds);
snprintf(time_unknown_string, sizeof(time_unknown_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds);
snprintf(time_unknown_scheduled_string, sizeof(time_unknown_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_unknown - temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds);
snprintf(time_unknown_unscheduled_string, sizeof(time_unknown_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
/* critical states */
get_time_breakdown(temp_subject->time_critical, &days, &hours, &minutes, &seconds);
snprintf(time_critical_string, sizeof(time_critical_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds);
snprintf(time_critical_scheduled_string, sizeof(time_critical_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_critical - temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds);
snprintf(time_critical_unscheduled_string, sizeof(time_critical_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
/* indeterminate time */
get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds);
snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds);
snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
get_time_breakdown(total_time, &days, &hours, &minutes, &seconds);
snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
if(total_time > 0) {
percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
percent_time_ok_scheduled = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)total_time);
percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled;
percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
percent_time_warning_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled;
percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
percent_time_unknown_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled;
percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
percent_time_critical_scheduled = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)total_time);
percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled;
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
percent_time_ok_scheduled_known = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)time_determinate);
percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known;
percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
percent_time_warning_scheduled_known = (double)(((double)temp_subject->scheduled_time_warning * 100.0) / (double)time_determinate);
percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known;
percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
percent_time_unknown_scheduled_known = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)time_determinate);
percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known;
percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
percent_time_critical_scheduled_known = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)time_determinate);
percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known;
}
}
printf("Service State Breakdowns:
\n");
#ifdef USE_TRENDS
printf("\n");
printf("", url_encode(svc_description), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_service_state, backtrack_archives);
printf(" ", url_encode(svc_description), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_service_state, backtrack_archives);
printf(" \n");
printf("
\n");
#endif
printf("\n");
printf("
\n");
printf("State Type / Reason Time %% Total Time %% Known Time \n");
/* ok states */
printf("OK ");
printf("Unscheduled %s %2.3f%% %2.3f%% \n", time_ok_unscheduled_string, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known);
printf("Scheduled %s %2.3f%% %2.3f%% \n", time_ok_scheduled_string, percent_time_ok_scheduled, percent_time_ok_scheduled_known);
printf("Total %s %2.3f%% %2.3f%% \n", time_ok_string, percent_time_ok, percent_time_ok_known);
/* warning states */
printf("WARNING ");
printf("Unscheduled %s %2.3f%% %2.3f%% \n", time_warning_unscheduled_string, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known);
printf("Scheduled %s %2.3f%% %2.3f%% \n", time_warning_scheduled_string, percent_time_warning_scheduled, percent_time_warning_scheduled_known);
printf("Total %s %2.3f%% %2.3f%% \n", time_warning_string, percent_time_warning, percent_time_warning_known);
/* unknown states */
printf("UNKNOWN ");
printf("Unscheduled %s %2.3f%% %2.3f%% \n", time_unknown_unscheduled_string, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known);
printf("Scheduled %s %2.3f%% %2.3f%% \n", time_unknown_scheduled_string, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known);
printf("Total %s %2.3f%% %2.3f%% \n", time_unknown_string, percent_time_unknown, percent_time_unknown_known);
/* critical states */
printf("CRITICAL ");
printf("Unscheduled %s %2.3f%% %2.3f%% \n", time_critical_unscheduled_string, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known);
printf("Scheduled %s %2.3f%% %2.3f%% \n", time_critical_scheduled_string, percent_time_critical_scheduled, percent_time_critical_scheduled_known);
printf("Total %s %2.3f%% %2.3f%% \n", time_critical_string, percent_time_critical, percent_time_critical_known);
printf("Undetermined ");
/*
printf("Unscheduled %s %2.3f%% \n",time_indeterminate_unscheduled_string,percent_time_indeterminate_unscheduled);
printf("Scheduled %s %2.3f%% \n",time_indeterminate_scheduled_string,percent_time_indeterminate_scheduled);
*/
printf("Nagios Not Running %s %2.3f%% \n", time_indeterminate_notrunning_string, percent_time_indeterminate_notrunning);
printf("Insufficient Data %s %2.3f%% \n", time_indeterminate_nodata_string, percent_time_indeterminate_nodata);
printf("Total %s %2.3f%% \n", time_indeterminate_string, percent_time_indeterminate);
printf(" \n");
printf("All Total %s 100.000%% 100.000%% \n", total_time_string);
printf("
\n");
printf("
\n");
write_log_entries(temp_subject);
}
/* display data for all services */
else {
if(output_format == HTML_OUTPUT) {
printf("Service State Breakdowns:
\n");
printf("\n");
printf("
\n");
printf("Host Service %% Time OK %% Time Warning %% Time Unknown %% Time Critical %% Time Undetermined \n");
}
else if(output_format == CSV_OUTPUT) {
printf("HOST_NAME, SERVICE_DESCRIPTION,");
printf(" TIME_OK_SCHEDULED, PERCENT_TIME_OK_SCHEDULED, PERCENT_KNOWN_TIME_OK_SCHEDULED, TIME_OK_UNSCHEDULED, PERCENT_TIME_OK_UNSCHEDULED, PERCENT_KNOWN_TIME_OK_UNSCHEDULED, TOTAL_TIME_OK, PERCENT_TOTAL_TIME_OK, PERCENT_KNOWN_TIME_OK,");
printf(" TIME_WARNING_SCHEDULED, PERCENT_TIME_WARNING_SCHEDULED, PERCENT_KNOWN_TIME_WARNING_SCHEDULED, TIME_WARNING_UNSCHEDULED, PERCENT_TIME_WARNING_UNSCHEDULED, PERCENT_KNOWN_TIME_WARNING_UNSCHEDULED, TOTAL_TIME_WARNING, PERCENT_TOTAL_TIME_WARNING, PERCENT_KNOWN_TIME_WARNING,");
printf(" TIME_UNKNOWN_SCHEDULED, PERCENT_TIME_UNKNOWN_SCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_SCHEDULED, TIME_UNKNOWN_UNSCHEDULED, PERCENT_TIME_UNKNOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_UNSCHEDULED, TOTAL_TIME_UNKNOWN, PERCENT_TOTAL_TIME_UNKNOWN, PERCENT_KNOWN_TIME_UNKNOWN,");
printf(" TIME_CRITICAL_SCHEDULED, PERCENT_TIME_CRITICAL_SCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_SCHEDULED, TIME_CRITICAL_UNSCHEDULED, PERCENT_TIME_CRITICAL_UNSCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_UNSCHEDULED, TOTAL_TIME_CRITICAL, PERCENT_TOTAL_TIME_CRITICAL, PERCENT_KNOWN_TIME_CRITICAL,");
printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n");
}
for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
if(temp_subject->type != SERVICE_SUBJECT)
continue;
temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
if(temp_service == NULL)
continue;
/* the user isn't authorized to view this service */
if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
continue;
current_subject++;
time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
time_indeterminate = total_time - time_determinate;
/* adjust indeterminate time due to insufficient data (not all was caught) */
temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
/* initialize values */
percent_time_ok = 0.0;
percent_time_ok_scheduled = 0.0;
percent_time_ok_unscheduled = 0.0;
percent_time_warning = 0.0;
percent_time_warning_scheduled = 0.0;
percent_time_warning_unscheduled = 0.0;
percent_time_unknown = 0.0;
percent_time_unknown_scheduled = 0.0;
percent_time_unknown_unscheduled = 0.0;
percent_time_critical = 0.0;
percent_time_critical_scheduled = 0.0;
percent_time_critical_unscheduled = 0.0;
percent_time_indeterminate = 0.0;
percent_time_indeterminate_scheduled = 0.0;
percent_time_indeterminate_unscheduled = 0.0;
percent_time_indeterminate_notrunning = 0.0;
percent_time_indeterminate_nodata = 0.0;
percent_time_ok_known = 0.0;
percent_time_ok_scheduled_known = 0.0;
percent_time_ok_unscheduled_known = 0.0;
percent_time_warning_known = 0.0;
percent_time_warning_scheduled_known = 0.0;
percent_time_warning_unscheduled_known = 0.0;
percent_time_unknown_known = 0.0;
percent_time_unknown_scheduled_known = 0.0;
percent_time_unknown_unscheduled_known = 0.0;
percent_time_critical_known = 0.0;
percent_time_critical_scheduled_known = 0.0;
percent_time_critical_unscheduled_known = 0.0;
if(total_time > 0) {
percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
percent_time_ok_scheduled = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)total_time);
percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled;
percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
percent_time_warning_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled;
percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
percent_time_unknown_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled;
percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
percent_time_critical_scheduled = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)total_time);
percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled;
percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
if(time_determinate > 0) {
percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
percent_time_ok_scheduled_known = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)time_determinate);
percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known;
percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
percent_time_warning_scheduled_known = (double)(((double)temp_subject->scheduled_time_warning * 100.0) / (double)time_determinate);
percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known;
percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
percent_time_unknown_scheduled_known = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)time_determinate);
percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known;
percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
percent_time_critical_scheduled_known = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)time_determinate);
percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known;
}
}
if(output_format == HTML_OUTPUT) {
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("", bgclass, bgclass);
if(strcmp(temp_subject->host_name, last_host))
host_report_url(temp_subject->host_name, temp_subject->host_name);
printf(" ", bgclass);
service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description);
printf(" %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate);
}
else if(output_format == CSV_OUTPUT) {
/* host name and service description */
printf("\"%s\", \"%s\",", temp_subject->host_name, temp_subject->service_description);
/* ok times */
printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_ok, percent_time_ok_scheduled, percent_time_ok_scheduled_known, temp_subject->time_ok - temp_subject->scheduled_time_ok, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known, temp_subject->time_ok, percent_time_ok, percent_time_ok_known);
/* warning times */
printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_warning, percent_time_warning_scheduled, percent_time_warning_scheduled_known, temp_subject->time_warning - temp_subject->scheduled_time_warning, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known, temp_subject->time_warning, percent_time_warning, percent_time_warning_known);
/* unknown times */
printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_unknown, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known, temp_subject->time_unknown - temp_subject->scheduled_time_unknown, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known, temp_subject->time_unknown, percent_time_unknown, percent_time_unknown_known);
/* critical times */
printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_critical, percent_time_critical_scheduled, percent_time_critical_scheduled_known, temp_subject->time_critical - temp_subject->scheduled_time_critical, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known, temp_subject->time_critical, percent_time_critical, percent_time_critical_known);
/* indeterminate times */
printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning, temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata, time_indeterminate, percent_time_indeterminate);
}
strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1);
last_host[sizeof(last_host) - 1] = '\x0';
get_running_average(&average_percent_time_ok, percent_time_ok, current_subject);
get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject);
get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject);
get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject);
get_running_average(&average_percent_time_warning, percent_time_warning, current_subject);
get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject);
get_running_average(&average_percent_time_critical, percent_time_critical, current_subject);
get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject);
get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
}
if(output_format == HTML_OUTPUT) {
/* average statistics */
if(odd) {
odd = 0;
bgclass = "Odd";
}
else {
odd = 1;
bgclass = "Even";
}
printf("Average %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% (%2.3f%%) %2.3f%% \n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate);
printf("
\n");
printf("
\n");
}
}
return;
}
void host_report_url(char *hn, char *label) {
printf("%s ", label);
return;
}
void service_report_url(char *hn, char *sd, char *label) {
printf("%s ", label);
return;
}
/* calculates running average */
void get_running_average(double *running_average, double new_value, int current_item) {
*running_average = (((*running_average * ((double)current_item - 1.0)) + new_value) / (double)current_item);
return;
}
/* used in reports where a timeperiod is selected */
unsigned long calculate_total_time(time_t start_time, time_t end_time) {
struct tm *t;
unsigned long midnight_today;
int weekday;
unsigned long total_time;
timerange *temp_timerange;
unsigned long temp_duration;
unsigned long temp_end;
unsigned long temp_start;
unsigned long start;
unsigned long end;
/* attempt to handle the current time_period */
if(current_timeperiod != NULL) {
/* "A day" is 86400 seconds */
t = localtime(&start_time);
/* calculate the start of the day (midnight, 00:00 hours) */
t->tm_sec = 0;
t->tm_min = 0;
t->tm_hour = 0;
t->tm_isdst = -1;
midnight_today = (unsigned long)mktime(t);
weekday = t->tm_wday;
total_time = 0;
while(midnight_today < end_time) {
temp_duration = 0;
temp_end = min(86400, t2 - midnight_today);
temp_start = 0;
if(t1 > midnight_today)
temp_start = t1 - midnight_today;
/* check all time ranges for this day of the week */
for(temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) {
start = max(temp_timerange->range_start, temp_start);
end = min(temp_timerange->range_end, temp_end);
#ifdef DEBUG
printf(" Matching in timerange[%d]: %d -> %d (%ld -> %ld) %d -> %d = %ld \n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end, start, end, end - start);
#endif
if(end > start)
temp_duration += end - start;
}
total_time += temp_duration;
temp_start = 0;
midnight_today += 86400;
if(++weekday > 6)
weekday = 0;
}
return total_time;
}
/* no timeperiod was selected */
return end_time - start_time;
}