/************************************************************************** * * HISTOGRAM.C - Nagios Alert Histogram CGI * * Copyright (c) 2001-2007 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-21-2007 * * License: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" #include /* Boutell's GD library function */ #include /* GD library small font definition */ /*#define DEBUG 1*/ #define HISTOGRAM_IMAGE "histogram.png" /* archived state types */ #define AS_NO_DATA 0 #define AS_PROGRAM_START 1 #define AS_PROGRAM_END 2 #define AS_HOST_UP 3 #define AS_HOST_DOWN 4 #define AS_HOST_UNREACHABLE 5 #define AS_SVC_OK 6 #define AS_SVC_UNKNOWN 7 #define AS_SVC_WARNING 8 #define AS_SVC_CRITICAL 9 /* display types */ #define DISPLAY_HOST_HISTOGRAM 0 #define DISPLAY_SERVICE_HISTOGRAM 1 #define DISPLAY_NO_HISTOGRAM 2 /* input types */ #define GET_INPUT_NONE 0 #define GET_INPUT_TARGET_TYPE 1 #define GET_INPUT_HOST_TARGET 2 #define GET_INPUT_SERVICE_TARGET 3 #define GET_INPUT_OPTIONS 4 /* breakdown types */ #define BREAKDOWN_MONTHLY 0 #define BREAKDOWN_DAY_OF_MONTH 1 #define BREAKDOWN_DAY_OF_WEEK 2 #define BREAKDOWN_HOURLY 3 /* modes */ #define CREATE_HTML 0 #define CREATE_IMAGE 1 /* standard report times */ #define TIMEPERIOD_CUSTOM 0 #define TIMEPERIOD_TODAY 1 #define TIMEPERIOD_YESTERDAY 2 #define TIMEPERIOD_THISWEEK 3 #define TIMEPERIOD_LASTWEEK 4 #define TIMEPERIOD_THISMONTH 5 #define TIMEPERIOD_LASTMONTH 6 #define TIMEPERIOD_THISQUARTER 7 #define TIMEPERIOD_LASTQUARTER 8 #define TIMEPERIOD_THISYEAR 9 #define TIMEPERIOD_LASTYEAR 10 #define TIMEPERIOD_LAST24HOURS 11 #define TIMEPERIOD_LAST7DAYS 12 #define TIMEPERIOD_LAST31DAYS 13 #define MAX_ARCHIVE_SPREAD 65 #define MAX_ARCHIVE 65 #define MAX_ARCHIVE_BACKTRACKS 60 #define DRAWING_WIDTH 550 #define DRAWING_HEIGHT 195 #define DRAWING_X_OFFSET 60 #define DRAWING_Y_OFFSET 235 #define GRAPH_HOST_UP 1 #define GRAPH_HOST_DOWN 2 #define GRAPH_HOST_UNREACHABLE 4 #define GRAPH_SERVICE_OK 8 #define GRAPH_SERVICE_WARNING 16 #define GRAPH_SERVICE_UNKNOWN 32 #define GRAPH_SERVICE_CRITICAL 64 #define GRAPH_HOST_PROBLEMS 6 #define GRAPH_HOST_ALL 7 #define GRAPH_SERVICE_PROBLEMS 112 #define GRAPH_SERVICE_ALL 120 #define GRAPH_EVERYTHING 255 #define GRAPH_SOFT_STATETYPES 1 #define GRAPH_HARD_STATETYPES 2 #define GRAPH_ALL_STATETYPES 3 extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char physical_images_path[MAX_FILENAME_LENGTH]; extern int log_rotation_method; extern host *host_list; extern service *service_list; authdata current_authdata; typedef struct timeslice_data_struct{ unsigned long service_ok; unsigned long host_up; unsigned long service_critical; unsigned long host_down; unsigned long service_unknown; unsigned long host_unreachable; unsigned long service_warning; }timeslice_data; timeslice_data *tsdata; void convert_timeperiod_to_times(int); void compute_report_times(void); void graph_all_histogram_data(void); void add_archived_state(int,time_t); void read_archived_state_data(void); void scan_log_file_for_archived_state_data(char *); void draw_line(int,int,int,int,int); void draw_dashed_line(int,int,int,int,int); void document_header(int); void document_footer(void); int process_cgivars(void); time_t t1; time_t t2; int start_second=0; int start_minute=0; int start_hour=0; int start_day=1; int start_month=1; int start_year=2000; int end_second=0; int end_minute=0; int end_hour=24; int end_day=1; int end_month=1; int end_year=2000; int display_type=DISPLAY_NO_HISTOGRAM; int mode=CREATE_HTML; int input_type=GET_INPUT_NONE; int timeperiod_type=TIMEPERIOD_LAST24HOURS; int breakdown_type=BREAKDOWN_HOURLY; int compute_time_from_parts=FALSE; int initial_states_logged=FALSE; int assume_state_retention=TRUE; int new_states_only=FALSE; int last_state=AS_NO_DATA; int program_restart_has_occurred=FALSE; int graph_events=GRAPH_EVERYTHING; int graph_statetypes=GRAPH_HARD_STATETYPES; int embedded=FALSE; int display_header=TRUE; char *host_name=""; char *svc_description=""; gdImagePtr histogram_image=0; int color_white=0; int color_black=0; int color_red=0; int color_darkred=0; int color_green=0; int color_yellow=0; int color_orange=0; int color_lightgray=0; FILE *image_file=NULL; int backtrack_archives=0; int earliest_archive=0; time_t earliest_time; time_t latest_time; int image_width=900; int image_height=320; int total_buckets=96; int main(int argc, char **argv){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char image_template[MAX_INPUT_BUFFER]; char start_timestring[MAX_INPUT_BUFFER]; char end_timestring[MAX_INPUT_BUFFER]; host *temp_host; service *temp_service; int is_authorized=TRUE; int found=FALSE; int days,hours,minutes,seconds; char *first_service=NULL; int x; time_t t3; time_t current_time; struct tm *t; /* initialize time period to last 24 hours */ time(&t2); t1=(time_t)(t2-(60*60*24)); /* get the arguments passed in the URL */ process_cgivars(); /* reset internal CGI variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); } return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); } return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); object_data_error(); document_footer(); } return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); status_data_error(); document_footer(); } free_memory(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if(compute_time_from_parts==TRUE) compute_report_times(); /* make sure times are sane, otherwise swap them */ if(t2\n"); printf("\n"); /* left column of the first row */ printf("\n"); if(display_type==DISPLAY_HOST_HISTOGRAM) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Alert Histogram"); else if(display_type==DISPLAY_SERVICE_HISTOGRAM) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Alert Histogram"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host and Service Alert Histogram"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); /* center column of top row */ printf("\n"); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ printf("
\n"); if(display_type==DISPLAY_HOST_HISTOGRAM) printf("Host '%s'",host_name); else if(display_type==DISPLAY_SERVICE_HISTOGRAM) printf("Service '%s' On Host '%s'",svc_description,host_name); printf("
\n"); printf("
\n"); printf("%s Event Histogram\n",url_images_path,TRENDS_ICON,(display_type==DISPLAY_HOST_HISTOGRAM)?"Host":"Service",(display_type==DISPLAY_HOST_HISTOGRAM)?"Host":"Service"); printf("
\n"); get_time_string(&t1,start_timestring,sizeof(start_timestring)-1,SHORT_DATE_TIME); get_time_string(&t2,end_timestring,sizeof(end_timestring)-1,SHORT_DATE_TIME); printf("
%s to %s
\n",start_timestring,end_timestring); get_time_breakdown((time_t)(t2-t1),&days,&hours,&minutes,&seconds); printf("
Duration: %dd %dh %dm %ds
\n",days,hours,minutes,seconds); } printf("\n"); /* right hand column of top row */ printf("\n"); printf("\n"); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ printf("\n",HISTOGRAM_CGI); printf("\n",(unsigned long)t1); printf("\n",(unsigned long)t2); printf("\n",host_name); if(display_type==DISPLAY_SERVICE_HISTOGRAM) printf("\n",svc_description); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } /* display context-sensitive help */ printf("\n"); printf("
Report period:Assume state retention:
\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Breakdown type:Initial states logged:
\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Events to graph:Ignore repeated states:
\n"); printf("\n"); printf("\n"); printf("\n"); printf("
State types to graph:
\n"); printf("\n"); printf("\n"); printf("\n"); printf("
\n"); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ if(display_type==DISPLAY_HOST_HISTOGRAM) display_context_help(CONTEXTHELP_HISTOGRAM_HOST); else display_context_help(CONTEXTHELP_HISTOGRAM_SERVICE); } else if(display_type==DISPLAY_NO_HISTOGRAM || input_type!=GET_INPUT_NONE){ if(input_type==GET_INPUT_NONE) display_context_help(CONTEXTHELP_HISTOGRAM_MENU1); else if(input_type==GET_INPUT_TARGET_TYPE) display_context_help(CONTEXTHELP_HISTOGRAM_MENU1); else if(input_type==GET_INPUT_HOST_TARGET) display_context_help(CONTEXTHELP_HISTOGRAM_MENU2); else if(input_type==GET_INPUT_SERVICE_TARGET) display_context_help(CONTEXTHELP_HISTOGRAM_MENU3); else if(input_type==GET_INPUT_OPTIONS) display_context_help(CONTEXTHELP_HISTOGRAM_MENU4); } printf("
\n"); printf("\n"); /* end of top table */ printf("\n"); printf("\n"); } /* check authorization... */ if(display_type==DISPLAY_HOST_HISTOGRAM){ temp_host=find_host(host_name); if(temp_host==NULL || is_authorized_for_host(temp_host,¤t_authdata)==FALSE) is_authorized=FALSE; } else if(display_type==DISPLAY_SERVICE_HISTOGRAM){ temp_service=find_service(host_name,svc_description); if(temp_service==NULL || is_authorized_for_service(temp_service,¤t_authdata)==FALSE) is_authorized=FALSE; } if(is_authorized==FALSE){ if(mode==CREATE_HTML) printf("

It appears as though you are not authorized to view information for the specified %s...

\n",(display_type==DISPLAY_HOST_HISTOGRAM)?"host":"service"); document_footer(); free_memory(); return ERROR; } if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ /* print URL to image */ if(mode==CREATE_HTML){ printf("

\n"); printf("
\n"); printf("\n"); printf("
\n"); } /* read and process state data */ else{ /* allocate memory */ tsdata=NULL; if(breakdown_type==BREAKDOWN_MONTHLY) total_buckets=12; else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) total_buckets=31; else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) total_buckets=7; else total_buckets=96; tsdata=(timeslice_data *)malloc(sizeof(timeslice_data)*total_buckets); if(tsdata==NULL) return ERROR; for(x=0;x
\n"); printf("
Step 2: Select Host
\n"); printf("

\n"); printf("

\n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Host:\n"); printf("\n"); printf("
\n"); printf("\n"); printf("
\n"); printf("

\n"); } /* ask the user for what service they want a report for */ else if(input_type==GET_INPUT_SERVICE_TARGET){ printf("\n"); printf("

\n"); printf("
Step 2: Select Service
\n"); printf("

\n"); printf("

\n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n"); printf("\n",(first_service==NULL)?"unknown":first_service); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Service:\n"); printf("\n"); printf("
\n"); printf("\n"); printf("
\n"); printf("

\n"); } /* ask the user for report range and options */ else if(input_type==GET_INPUT_OPTIONS){ time(¤t_time); t=localtime(¤t_time); start_day=1; start_year=t->tm_year+1900; end_day=t->tm_mday; end_year=t->tm_year+1900; printf("

\n"); printf("
Step 3: Select Report Options
\n"); printf("

\n"); printf("

\n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n",host_name); if(display_type==DISPLAY_SERVICE_HISTOGRAM) printf("\n",svc_description); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Report Period:\n"); printf("\n"); printf("
If Custom Report Period...
Start Date (Inclusive):"); printf("\n "); printf(" ",start_day); printf("",start_year); printf("\n"); printf("\n"); printf("\n"); printf("
End Date (Inclusive):"); printf("\n "); printf(" ",end_day); printf("",end_year); printf("\n"); printf("\n"); printf("\n"); printf("

Statistics Breakdown:\n"); printf("\n"); printf("
Events To Graph:\n"); printf("\n"); printf("
State Types To Graph:\n"); printf("\n"); printf("
Assume State Retention:\n"); printf("\n"); printf("
Initial States Logged:\n"); printf("\n"); printf("
Ignore Repeated States:\n"); printf("\n"); printf("
\n"); printf("

\n"); } /* as the user whether they want a graph for a host or service */ else{ printf("

\n"); printf("
Step 1: Select Report Type
\n"); printf("

\n"); printf("

\n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Type:\n"); printf("\n"); printf("
\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; if(mode==CREATE_HTML){ 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); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios Histogram\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,HISTOGRAM_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(HISTOGRAM_CGI,SSI_HEADER); printf("
\n"); } else{ 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)0L; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-Type: image/png\r\n\r\n"); } return; } void document_footer(void){ if(embedded==TRUE) return; if(mode==CREATE_HTML){ /* include user SSI footer */ include_ssi_files(HISTOGRAM_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 host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); strip_html_brackets(host_name); display_type=DISPLAY_HOST_HISTOGRAM; } /* we found the node width argument */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } svc_description=(char *)malloc(strlen(variables[x])+1); if(svc_description==NULL) svc_description=""; else strcpy(svc_description,variables[x]); strip_html_brackets(svc_description); display_type=DISPLAY_SERVICE_HISTOGRAM; } /* 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; } /* 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; } /* we found the image creation option */ else if(!strcmp(variables[x],"createimage")){ mode=CREATE_IMAGE; } /* 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; } /* 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 timeperiod_type=TIMEPERIOD_TODAY; if(timeperiod_type!=TIMEPERIOD_CUSTOM) convert_timeperiod_to_times(timeperiod_type); } /* 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 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 input option */ else if(!strcmp(variables[x],"input")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"gethost")) input_type=GET_INPUT_HOST_TARGET; else if(!strcmp(variables[x],"getservice")) input_type=GET_INPUT_SERVICE_TARGET; else if(!strcmp(variables[x],"getoptions")) input_type=GET_INPUT_OPTIONS; else input_type=GET_INPUT_TARGET_TYPE; } /* we found the graph states option */ else if(!strcmp(variables[x],"graphevents")){ x++; if(variables[x]==NULL){ error=TRUE; break; } graph_events=atoi(variables[x]); } /* we found the graph state types option */ else if(!strcmp(variables[x],"graphstatetypes")){ x++; if(variables[x]==NULL){ error=TRUE; break; } graph_statetypes=atoi(variables[x]); } /* we found the breakdown option */ else if(!strcmp(variables[x],"breakdown")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"monthly")) breakdown_type=BREAKDOWN_MONTHLY; else if(!strcmp(variables[x],"dayofmonth")) breakdown_type=BREAKDOWN_DAY_OF_MONTH; else if(!strcmp(variables[x],"dayofweek")) breakdown_type=BREAKDOWN_DAY_OF_WEEK; else breakdown_type=BREAKDOWN_HOURLY; } /* 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 initial states logged option */ else if(!strcmp(variables[x],"initialstateslogged")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) initial_states_logged=TRUE; else initial_states_logged=FALSE; } /* we found the new states only option */ else if(!strcmp(variables[x],"newstatesonly")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) new_states_only=TRUE; else new_states_only=FALSE; } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* graphs histogram data */ void graph_all_histogram_data(void){ int pixel_x; int pixel_y; int last_pixel_y; int current_bucket; int actual_bucket; unsigned long max_value; double x_scaling_factor; double y_scaling_factor; double x_units; double y_units; int current_unit; int actual_unit; char temp_buffer[MAX_INPUT_BUFFER]; int string_width; int string_height; char *days[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; char *months[12]={"January","February","March","April","May","June","July","August","September","October","November","December"}; char start_time[MAX_INPUT_BUFFER]; char end_time[MAX_INPUT_BUFFER]; unsigned long state1_max=0L; unsigned long state1_min=0L; int have_state1_min=FALSE; unsigned long state1_sum=0L; double state1_avg=0.0; unsigned long state2_max=0L; unsigned long state2_min=0L; int have_state2_min=FALSE; unsigned long state2_sum=0L; double state2_avg=0.0; unsigned long state3_max=0L; unsigned long state3_min=0L; int have_state3_min=FALSE; unsigned long state3_sum=0L; double state3_avg=0.0; unsigned long state4_max=0L; unsigned long state4_min=0L; int have_state4_min=FALSE; unsigned long state4_sum=0L; double state4_avg=0.0; #ifdef DEBUG printf("Total Buckets: %d\n",total_buckets); #endif /* determine max value in the buckets (for scaling) */ max_value=0L; for(current_bucket=0;current_bucketmax_value) max_value=tsdata[current_bucket].service_ok; if(tsdata[current_bucket].service_warning>max_value) max_value=tsdata[current_bucket].service_warning; if(tsdata[current_bucket].service_unknown>max_value) max_value=tsdata[current_bucket].service_unknown; if(tsdata[current_bucket].service_critical>max_value) max_value=tsdata[current_bucket].service_critical; if(tsdata[current_bucket].host_up>max_value) max_value=tsdata[current_bucket].host_up; if(tsdata[current_bucket].host_down>max_value) max_value=tsdata[current_bucket].host_down; if(tsdata[current_bucket].host_unreachable>max_value) max_value=tsdata[current_bucket].host_unreachable; } #ifdef DEBUG printf("Done determining max bucket values\n"); printf("MAX_VALUE=%lu\n",max_value); printf("DRAWING_HEIGHT=%lu\n",DRAWING_HEIGHT); #endif /* min number of values to graph */ if(max_value<10) max_value=10; #ifdef DEBUG printf("ADJUSTED MAX_VALUE=%lu\n",max_value); #endif /* determine y scaling factor */ /*y_scaling_factor=floor((double)DRAWING_HEIGHT/(double)max_value);*/ y_scaling_factor=(double)((double)DRAWING_HEIGHT/(double)max_value); /* determine x scaling factor */ x_scaling_factor=(double)((double)DRAWING_WIDTH/(double)total_buckets); /* determine y units resolution - we want a max of about 10 y grid lines */ /* y_units=(double)((double)DRAWING_HEIGHT/19.0); y_units=ceil(y_units/y_scaling_factor)*y_scaling_factor; */ y_units=ceil(19.0/y_scaling_factor); /* determine x units resolution */ if(breakdown_type==BREAKDOWN_HOURLY) x_units=(double)((double)DRAWING_WIDTH/(double)(total_buckets/4.0)); else x_units=x_scaling_factor; #ifdef DEBUG printf("DRAWING_WIDTH: %d\n",DRAWING_WIDTH); printf("DRAWING_HEIGHT: %d\n",DRAWING_HEIGHT); printf("max_value: %lu\n",max_value); printf("x_scaling_factor: %.3f\n",x_scaling_factor); printf("y_scaling_factor: %.3f\n",y_scaling_factor); printf("x_units: %.3f\n",x_units); printf("y_units: %.3f\n",y_units); printf("y units to draw: %.3f\n",((double)max_value/y_units)); #endif string_height=gdFontSmall->h; #ifdef DEBUG printf("Starting to draw Y grid lines...\n"); #endif /* draw y grid lines */ if(max_value>0){ for(current_unit=1;(current_unit*y_units*y_scaling_factor)<=DRAWING_HEIGHT;current_unit++){ draw_dashed_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor),DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor),color_lightgray); #ifdef DEBUG printf(" Drawing Y unit #%d @ %d\n",current_unit,(int)(current_unit*y_units*y_scaling_factor)); #endif } } #ifdef DEBUG printf("Starting to draw X grid lines...\n"); #endif /* draw x grid lines */ for(current_unit=1;(int)(current_unit*x_units)<=DRAWING_WIDTH;current_unit++) draw_dashed_line(DRAWING_X_OFFSET+(int)(current_unit*x_units),DRAWING_Y_OFFSET,DRAWING_X_OFFSET+(int)(current_unit*x_units),DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_lightgray); #ifdef DEBUG printf("Starting to draw grid units...\n"); #endif /* draw y units */ if(max_value>0){ for(current_unit=0;(current_unit*y_units*y_scaling_factor)<=DRAWING_HEIGHT;current_unit++){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"%d",(int)(current_unit*y_units)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET-string_width-5,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor)-(string_height/2),(unsigned char *)temp_buffer,color_black); } } /* draw x units */ for(current_unit=0,actual_unit=0;(int)(current_unit*x_units)<=DRAWING_WIDTH;current_unit++,actual_unit++){ if(actual_unit>=total_buckets) actual_unit=0; if(breakdown_type==BREAKDOWN_MONTHLY) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",months[actual_unit]); else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%d",actual_unit+1); else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",days[actual_unit]); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"%02d:00",(actual_unit==24)?0:actual_unit); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageStringUp(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(current_unit*x_units)-(string_height/2),DRAWING_Y_OFFSET+5+string_width,(unsigned char *)temp_buffer,color_black); } /* draw y unit measure */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Number of Events"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageStringUp(histogram_image,gdFontSmall,0,DRAWING_Y_OFFSET-(DRAWING_HEIGHT/2)+(string_width/2),(unsigned char *)temp_buffer,color_black); /* draw x unit measure */ if(breakdown_type==BREAKDOWN_MONTHLY) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Month"); else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Day of the Month"); else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Day of the Week"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Hour of the Day (15 minute increments)"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),DRAWING_Y_OFFSET+70,(unsigned char *)temp_buffer,color_black); /* draw title */ snprintf(start_time,sizeof(start_time)-1,"%s",ctime(&t1)); start_time[sizeof(start_time)-1]='\x0'; start_time[strlen(start_time)-1]='\x0'; snprintf(end_time,sizeof(end_time)-1,"%s",ctime(&t2)); end_time[sizeof(end_time)-1]='\x0'; end_time[strlen(end_time)-1]='\x0'; if(display_type==DISPLAY_HOST_HISTOGRAM) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Event History For Host '%s'",host_name); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Event History For Service '%s' On Host '%s'",svc_description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),0,(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s to %s",start_time,end_time); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),string_height+5,(unsigned char *)temp_buffer,color_black); #ifdef DEBUG printf("About to starting graphing (total_buckets=%d)...\n",total_buckets); #endif /* graph service states */ if(display_type==DISPLAY_HOST_HISTOGRAM){ /* graph host recoveries */ if(graph_events & GRAPH_HOST_UP){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].host_up*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_green); last_pixel_y=pixel_y; if(current_bucketstate1_max) state1_max=tsdata[actual_bucket].host_up; state1_sum+=tsdata[actual_bucket].host_up; } } } #ifdef DEBUG printf("Done graphing HOST UP states...\n"); #endif /* graph host down states */ if(graph_events & GRAPH_HOST_DOWN){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].host_down*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_red); last_pixel_y=pixel_y; if(current_bucketstate2_max) state2_max=tsdata[actual_bucket].host_down; state2_sum+=tsdata[actual_bucket].host_down; } } } #ifdef DEBUG printf("Done graphing HOST DOWN states...\n"); #endif /* graph host unreachable states */ if(graph_events & GRAPH_HOST_UNREACHABLE){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].host_unreachable*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_darkred); last_pixel_y=pixel_y; if(current_bucketstate3_max) state3_max=tsdata[actual_bucket].host_unreachable; state3_sum+=tsdata[actual_bucket].host_unreachable; } } } #ifdef DEBUG printf("Done graphing HOST UNREACHABLE states...\n"); #endif } /* graph service states */ else{ /* graph service recoveries */ if(graph_events & GRAPH_SERVICE_OK){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_ok*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_green); last_pixel_y=pixel_y; if(current_bucketstate1_max) state1_max=tsdata[actual_bucket].service_ok; state1_sum+=tsdata[actual_bucket].service_ok; } } } /* graph service warning states */ if(graph_events & GRAPH_SERVICE_WARNING){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_warning*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_yellow); last_pixel_y=pixel_y; if(current_bucketstate2_max) state2_max=tsdata[actual_bucket].service_warning; state2_sum+=tsdata[actual_bucket].service_warning; } } } /* graph service unknown states */ if(graph_events & GRAPH_SERVICE_UNKNOWN){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_unknown*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_orange); last_pixel_y=pixel_y; if(current_bucketstate3_max) state3_max=tsdata[actual_bucket].service_unknown; state3_sum+=tsdata[actual_bucket].service_unknown; } } } /* graph service critical states */ if(graph_events & GRAPH_SERVICE_CRITICAL){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_critical*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_red); last_pixel_y=pixel_y; if(current_bucketstate4_max) state4_max=tsdata[actual_bucket].service_critical; state4_sum+=tsdata[actual_bucket].service_critical; } } } } #ifdef DEBUG printf("Done graphing states...\n"); #endif /* draw graph boundaries */ draw_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET,DRAWING_X_OFFSET,DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_black); draw_line(DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET,DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_black); draw_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET,DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET,color_black); /* graph stats */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"EVENT TYPE"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT,(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1," MIN MAX SUM AVG"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT,(unsigned char *)temp_buffer,color_black); draw_line(DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+string_height+2,DRAWING_X_OFFSET+DRAWING_WIDTH+275,DRAWING_Y_OFFSET-DRAWING_HEIGHT+string_height+2,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"Recovery (%s):",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Ok":"Up"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*1),(unsigned char *)temp_buffer,color_green); state1_avg=(double)((double)state1_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state1_min,state1_max,state1_sum,state1_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*1),(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s:",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Warning":"Down"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*2),(unsigned char *)temp_buffer,(display_type==DISPLAY_SERVICE_HISTOGRAM)?color_yellow:color_red); state2_avg=(double)((double)state2_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state2_min,state2_max,state2_sum,state2_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*2),(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s:",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Unknown":"Unreachable"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*3),(unsigned char *)temp_buffer,(display_type==DISPLAY_SERVICE_HISTOGRAM)?color_orange:color_darkred); state3_avg=(double)((double)state3_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state3_min,state3_max,state3_sum,state3_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*3),(unsigned char *)temp_buffer,color_black); if(display_type==DISPLAY_SERVICE_HISTOGRAM){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Critical:"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*4),(unsigned char *)temp_buffer,color_red); state4_avg=(double)((double)state4_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state4_min,state4_max,state4_sum,state4_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*4),(unsigned char *)temp_buffer,color_black); } return; } /* adds an archived state entry */ void add_archived_state(int state_type, time_t time_stamp){ struct tm *our_time; int bucket; int skip_state=FALSE; #ifdef DEBUG2 printf("NEW ENTRY: last=%d this=%d\n",last_state,state_type); #endif /* don't record program starts/stops, just make a note that one occurred */ if(state_type==AS_PROGRAM_START || state_type==AS_PROGRAM_END){ #ifdef DEBUG2 printf("Recording a program start: %d\n",state_type); #endif program_restart_has_occurred=TRUE; return; } /* see if we should even take into account this event */ if(program_restart_has_occurred==TRUE){ #ifdef DEBUG2 printf("program_restart_has_occurred: last=%d this=%d\n",last_state,state_type); #endif if(initial_states_logged==TRUE){ if(state_type==AS_SVC_OK && last_state==AS_SVC_OK) skip_state=TRUE; if(state_type==AS_HOST_UP && last_state==AS_HOST_UP) skip_state=TRUE; } if(assume_state_retention==TRUE && initial_states_logged==TRUE){ if(state_type==AS_SVC_WARNING && last_state==AS_SVC_WARNING) skip_state=TRUE; if(state_type==AS_SVC_UNKNOWN && last_state==AS_SVC_UNKNOWN) skip_state=TRUE; if(state_type==AS_SVC_CRITICAL && last_state==AS_SVC_CRITICAL) skip_state=TRUE; if(state_type==AS_HOST_DOWN && last_state==AS_HOST_DOWN) skip_state=TRUE; if(state_type==AS_HOST_UNREACHABLE && last_state==AS_HOST_UNREACHABLE) skip_state=TRUE; } if(skip_state==TRUE){ program_restart_has_occurred=FALSE; #ifdef DEBUG2 printf("Skipping state...\n"); #endif return; } } /* reset program restart variable */ program_restart_has_occurred=FALSE; /* are we only processing new states */ if(new_states_only==TRUE && state_type==last_state){ #ifdef DEBUG2 printf("Skipping state (not a new state)...\n"); #endif return; } #ifdef DEBUG2 printf("GOODSTATE: %d @ %lu\n",state_type,(unsigned long)time_stamp); #endif our_time=localtime(&time_stamp); /* calculate the correct bucket to dump the data into */ if(breakdown_type==BREAKDOWN_MONTHLY) bucket=our_time->tm_mon; else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) bucket=our_time->tm_mday-1; else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) bucket=our_time->tm_wday; else bucket=(our_time->tm_hour*4)+(our_time->tm_min/15); #ifdef DEBUG2 printf("\tBucket=%d\n",bucket); #endif /* save the data in the correct bucket */ if(state_type==AS_SVC_OK) tsdata[bucket].service_ok++; else if(state_type==AS_SVC_UNKNOWN) tsdata[bucket].service_unknown++; else if(state_type==AS_SVC_WARNING) tsdata[bucket].service_warning++; else if(state_type==AS_SVC_CRITICAL) tsdata[bucket].service_critical++; else if(state_type==AS_HOST_UP) tsdata[bucket].host_up++; else if(state_type==AS_HOST_DOWN) tsdata[bucket].host_down++; else if(state_type==AS_HOST_UNREACHABLE) tsdata[bucket].host_unreachable++; /* record last state type */ last_state=state_type; return; } /* reads log files for archived state data */ void read_archived_state_data(void){ char filename[MAX_FILENAME_LENGTH]; int newest_archive=0; int oldest_archive=0; int current_archive; #ifdef DEBUG2 printf("Determining archives to use...\n"); #endif /* determine earliest archive to use */ 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 */ newest_archive=determine_archive_to_use_from_time(t2); if(oldest_archivetm_sec=0; t->tm_min=0; t->tm_hour=0; 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: break; case TIMEPERIOD_LASTQUARTER: 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; 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; t2=mktime(et); } /* draws a solid line */ void draw_line(int x1,int y1,int x2,int y2,int color){ int styleSolid[1]; styleSolid[0]=color; /* sets current style to a solid line */ gdImageSetStyle(histogram_image,styleSolid,1); /* draws a line (dashed) */ gdImageLine(histogram_image,x1,y1,x2,y2,gdStyled); return; } /* draws a dashed line */ void draw_dashed_line(int x1,int y1,int x2,int y2,int color){ int styleDashed[6]; styleDashed[0]=color; styleDashed[1]=color; styleDashed[2]=gdTransparent; styleDashed[3]=gdTransparent; styleDashed[4]=gdTransparent; styleDashed[5]=gdTransparent; /* sets current style to a solid line */ gdImageSetStyle(histogram_image,styleDashed,6); /* draws a line (dashed) */ gdImageLine(histogram_image,x1,y1,x2,y2,gdStyled); return; }