Icinga-core 1.4.0
next gen monitoring
base/sehandlers.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * SEHANDLERS.C - Service and host event and state handlers for Icinga
00004  *
00005  * Copyright (c) 1999-2010 Ethan Galstad (egalstad@nagios.org)
00006  * Copyright (c) 2009-2011 Nagios Core Development Team and Community Contributors
00007  * Copyright (c) 2009-2011 Icinga Development Team (http://www.icinga.org)
00008  *
00009  * License:
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License version 2 as
00013  * published by the Free Software Foundation.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023  *
00024  *****************************************************************************/
00025 
00026 #include "../include/config.h"
00027 #include "../include/comments.h"
00028 #include "../include/common.h"
00029 #include "../include/statusdata.h"
00030 #include "../include/downtime.h"
00031 #include "../include/macros.h"
00032 #include "../include/icinga.h"
00033 #include "../include/perfdata.h"
00034 #include "../include/broker.h"
00035 
00036 #ifdef USE_EVENT_BROKER
00037 #include "../include/neberrors.h"
00038 #endif
00039 
00040 extern int             enable_event_handlers;
00041 extern int             obsess_over_services;
00042 extern int             obsess_over_hosts;
00043 
00044 extern int             log_event_handlers;
00045 extern int             log_host_retries;
00046 
00047 extern unsigned long   next_event_id;
00048 extern unsigned long   next_problem_id;
00049 
00050 extern int             event_handler_timeout;
00051 extern int             ocsp_timeout;
00052 extern int             ochp_timeout;
00053 
00054 extern char            *global_host_event_handler;
00055 extern char            *global_service_event_handler;
00056 extern command         *global_host_event_handler_ptr;
00057 extern command         *global_service_event_handler_ptr;
00058 
00059 extern char            *ocsp_command;
00060 extern char            *ochp_command;
00061 extern command         *ocsp_command_ptr;
00062 extern command         *ochp_command_ptr;
00063 
00064 extern time_t          program_start;
00065 
00066 int dummy;      /* reduce compiler warnings */
00067 
00068 /******************************************************************/
00069 /************* OBSESSIVE COMPULSIVE HANDLER FUNCTIONS *************/
00070 /******************************************************************/
00071 
00072 
00073 /* handles service check results in an obsessive compulsive manner... */
00074 int obsessive_compulsive_service_check_processor(service *svc){
00075         char *raw_command=NULL;
00076         char *processed_command=NULL;
00077         host *temp_host=NULL;
00078         int early_timeout=FALSE;
00079         double exectime=0.0;
00080         int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS;
00081         icinga_macros mac;
00082 
00083         log_debug_info(DEBUGL_FUNCTIONS,0,"obsessive_compulsive_service_check_processor()\n");
00084 
00085         if(svc==NULL)
00086                 return ERROR;
00087 
00088         /* bail out if we shouldn't be obsessing */
00089         if(obsess_over_services==FALSE)
00090                 return OK;
00091         if(svc->obsess_over_service==FALSE)
00092                 return OK;
00093 
00094         /* if there is no valid command, exit */
00095         if(ocsp_command==NULL)
00096                 return ERROR;
00097 
00098         /* find the associated host */
00099         if((temp_host=(host *)svc->host_ptr)==NULL)
00100                 return ERROR;
00101 
00102         /* update service macros */
00103         memset(&mac, 0, sizeof(mac));
00104         grab_host_macros_r(&mac, temp_host);
00105         grab_service_macros_r(&mac, svc);
00106 
00107         /* get the raw command line */
00108         get_raw_command_line_r(&mac, ocsp_command_ptr,ocsp_command,&raw_command,macro_options);
00109         if(raw_command==NULL) {
00110                 clear_volatile_macros_r(&mac);
00111                 return ERROR;
00112         }
00113         log_debug_info(DEBUGL_CHECKS,2,"Raw obsessive compulsive service processor command line: %s\n",raw_command);
00114 
00115         /* process any macros in the raw command line */
00116         process_macros_r(&mac, raw_command,&processed_command,macro_options);
00117         if(processed_command==NULL) {
00118                 clear_volatile_macros_r(&mac);
00119                 return ERROR;
00120         }
00121 
00122         log_debug_info(DEBUGL_CHECKS,2,"Processed obsessive compulsive service processor command line: %s\n",processed_command);
00123 
00124         /* run the command */
00125         my_system_r(&mac, processed_command,ocsp_timeout,&early_timeout,&exectime,NULL,0);
00126 
00127         clear_volatile_macros_r(&mac);
00128 
00129         /* check to see if the command timed out */
00130         if(early_timeout==TRUE)
00131                 logit(NSLOG_RUNTIME_WARNING,TRUE,"Warning: OCSP command '%s' for service '%s' on host '%s' timed out after %d seconds\n",processed_command,svc->description,svc->host_name,ocsp_timeout);
00132 
00133         /* free memory */
00134         my_free(raw_command);
00135         my_free(processed_command);
00136         
00137         return OK;
00138         }
00139 
00140 
00141 
00142 /* handles host check results in an obsessive compulsive manner... */
00143 int obsessive_compulsive_host_check_processor(host *hst){
00144         char *raw_command=NULL;
00145         char *processed_command=NULL;
00146         int early_timeout=FALSE;
00147         double exectime=0.0;
00148         int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS;
00149         icinga_macros mac;
00150 
00151         log_debug_info(DEBUGL_FUNCTIONS,0,"obsessive_compulsive_host_check_processor()\n");
00152 
00153         if(hst==NULL)
00154                 return ERROR;
00155 
00156         /* bail out if we shouldn't be obsessing */
00157         if(obsess_over_hosts==FALSE)
00158                 return OK;
00159         if(hst->obsess_over_host==FALSE)
00160                 return OK;
00161 
00162         /* if there is no valid command, exit */
00163         if(ochp_command==NULL)
00164                 return ERROR;
00165 
00166         /* update macros */
00167         memset(&mac, 0, sizeof(mac));
00168         grab_host_macros_r(&mac, hst);
00169 
00170         /* get the raw command line */
00171         get_raw_command_line_r(&mac, ochp_command_ptr,ochp_command,&raw_command,macro_options);
00172         if(raw_command==NULL) {
00173                 clear_volatile_macros_r(&mac);
00174                 return ERROR;
00175         }
00176 
00177         log_debug_info(DEBUGL_CHECKS,2,"Raw obsessive compulsive host processor command line: %s\n",raw_command);
00178 
00179         /* process any macros in the raw command line */
00180         process_macros_r(&mac, raw_command,&processed_command,macro_options);
00181         if(processed_command==NULL) {
00182                 clear_volatile_macros_r(&mac);
00183                 return ERROR;
00184         }
00185 
00186         log_debug_info(DEBUGL_CHECKS,2,"Processed obsessive compulsive host processor command line: %s\n",processed_command);
00187 
00188         /* run the command */
00189         my_system_r(&mac, processed_command,ochp_timeout,&early_timeout,&exectime,NULL,0);
00190         clear_volatile_macros_r(&mac);
00191 
00192         /* check to see if the command timed out */
00193         if(early_timeout==TRUE)
00194                 logit(NSLOG_RUNTIME_WARNING,TRUE,"Warning: OCHP command '%s' for host '%s' timed out after %d seconds\n",processed_command,hst->name,ochp_timeout);
00195 
00196         /* free memory */
00197         my_free(raw_command);
00198         my_free(processed_command);
00199 
00200         return OK;
00201 }
00202 
00203 
00204 
00205 
00206 /******************************************************************/
00207 /**************** SERVICE EVENT HANDLER FUNCTIONS *****************/
00208 /******************************************************************/
00209 
00210 
00211 /* handles changes in the state of a service */
00212 int handle_service_event(service *svc){
00213         host *temp_host=NULL;
00214         icinga_macros mac;
00215 
00216         log_debug_info(DEBUGL_FUNCTIONS,0,"handle_service_event()\n");
00217 
00218         if(svc==NULL)
00219                 return ERROR;
00220 
00221 #ifdef USE_EVENT_BROKER
00222         /* send event data to broker */
00223         broker_statechange_data(NEBTYPE_STATECHANGE_END,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_STATECHANGE,(void *)svc,svc->current_state,svc->state_type,svc->current_attempt,svc->max_attempts,NULL);
00224 #endif
00225 
00226         /* bail out if we shouldn't be running event handlers */
00227         if(enable_event_handlers==FALSE)
00228                 return OK;
00229         if(svc->event_handler_enabled==FALSE)
00230                 return OK;
00231 
00232         /* find the host */
00233         if((temp_host=(host *)svc->host_ptr)==NULL)
00234                 return ERROR;
00235 
00236         /* update service macros */
00237         memset(&mac, 0, sizeof(mac));
00238         grab_host_macros_r(&mac, temp_host);
00239         grab_service_macros_r(&mac, svc);
00240 
00241         /* run the global service event handler */
00242         run_global_service_event_handler(&mac, svc);
00243 
00244         /* run the event handler command if there is one */
00245         if(svc->event_handler!=NULL)
00246                 run_service_event_handler(&mac, svc);
00247         clear_volatile_macros_r(&mac);
00248 
00249         /* check for external commands - the event handler may have given us some directives... */
00250         check_for_external_commands();
00251 
00252         return OK;
00253 }
00254 
00255 
00256 
00257 /* runs the global service event handler */
00258 int run_global_service_event_handler(icinga_macros *mac, service *svc){
00259         char *raw_command=NULL;
00260         char *processed_command=NULL;
00261         char *raw_logentry=NULL;
00262         char *processed_logentry=NULL;
00263         char *command_output=NULL;
00264         int early_timeout=FALSE;
00265         double exectime=0.0;
00266         int result=0;
00267 #ifdef USE_EVENT_BROKER
00268         struct timeval start_time;
00269         struct timeval end_time;
00270         int neb_result=OK;
00271 #endif
00272         int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS;
00273 
00274 
00275         log_debug_info(DEBUGL_FUNCTIONS,0,"run_global_service_event_handler()\n");
00276 
00277         if(svc==NULL)
00278                 return ERROR;
00279 
00280         /* bail out if we shouldn't be running event handlers */
00281         if(enable_event_handlers==FALSE)
00282                 return OK;
00283 
00284         /* a global service event handler command has not been defined */
00285         if(global_service_event_handler==NULL)
00286                 return ERROR;
00287 
00288         log_debug_info(DEBUGL_EVENTHANDLERS,1,"Running global event handler for service '%s' on host '%s'...\n",svc->description,svc->host_name);
00289 
00290 #ifdef USE_EVENT_BROKER
00291         /* get start time */
00292         gettimeofday(&start_time,NULL);
00293 #endif
00294 
00295         /* get the raw command line */
00296         get_raw_command_line_r(mac, global_service_event_handler_ptr,global_service_event_handler,&raw_command,macro_options);
00297         if(raw_command==NULL) {
00298                 return ERROR;
00299         }
00300 
00301         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Raw global service event handler command line: %s\n",raw_command);
00302 
00303         /* process any macros in the raw command line */
00304         process_macros_r(mac, raw_command,&processed_command,macro_options);
00305         if(processed_command==NULL)
00306                 return ERROR;
00307 
00308         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Processed global service event handler command line: %s\n",processed_command);
00309 
00310         if(log_event_handlers==TRUE){
00311                 dummy=asprintf(&raw_logentry,"GLOBAL SERVICE EVENT HANDLER: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n",svc->host_name,svc->description,global_service_event_handler);
00312                 process_macros_r(mac, raw_logentry,&processed_logentry,macro_options);
00313                 logit(NSLOG_EVENT_HANDLER,FALSE,"%s",processed_logentry);
00314                 }
00315 
00316 #ifdef USE_EVENT_BROKER
00317         /* send event data to broker */
00318         end_time.tv_sec=0L;
00319         end_time.tv_usec=0L;
00320         neb_result=broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_service_event_handler,processed_command,NULL,NULL);
00321 
00322         /* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
00323         if(neb_result==NEBERROR_CALLBACKOVERRIDE) {
00324                 my_free(processed_command);
00325                 my_free(raw_command);
00326                 my_free(raw_logentry);
00327                 my_free(processed_logentry);
00328                 return OK;
00329         }
00330 #endif
00331 
00332         /* run the command */
00333         result=my_system_r(mac, processed_command,event_handler_timeout,&early_timeout,&exectime,&command_output,0);
00334 
00335         /* check to see if the event handler timed out */
00336         if(early_timeout==TRUE)
00337                 logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE,"Warning: Global service event handler command '%s' timed out after %d seconds\n",processed_command,event_handler_timeout);
00338 
00339 #ifdef USE_EVENT_BROKER
00340         /* get end time */
00341         gettimeofday(&end_time,NULL);
00342 #endif
00343 
00344 #ifdef USE_EVENT_BROKER
00345         /* send event data to broker */
00346         broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_service_event_handler,processed_command,command_output,NULL);
00347 #endif
00348 
00349         /* free memory */
00350         my_free(command_output);
00351         my_free(raw_command);
00352         my_free(processed_command);
00353         my_free(raw_logentry);
00354         my_free(processed_logentry);
00355 
00356         return OK;
00357 }
00358 
00359 
00360 
00361 /* runs a service event handler command */
00362 int run_service_event_handler(icinga_macros *mac, service *svc){
00363         char *raw_command=NULL;
00364         char *processed_command=NULL;
00365         char *raw_logentry=NULL;
00366         char *processed_logentry=NULL;
00367         char *command_output=NULL;
00368         int early_timeout=FALSE;
00369         double exectime=0.0;
00370         int result=0;
00371 #ifdef USE_EVENT_BROKER
00372         struct timeval start_time;
00373         struct timeval end_time;
00374         int neb_result=OK;
00375 #endif
00376         int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS;
00377 
00378 
00379         log_debug_info(DEBUGL_FUNCTIONS,0,"run_service_event_handler()\n");
00380 
00381         if(svc==NULL)
00382                 return ERROR;
00383 
00384         /* bail if there's no command */
00385         if(svc->event_handler==NULL)
00386                 return ERROR;
00387 
00388         log_debug_info(DEBUGL_EVENTHANDLERS,1,"Running event handler for service '%s' on host '%s'...\n",svc->description,svc->host_name);
00389 
00390 #ifdef USE_EVENT_BROKER
00391         /* get start time */
00392         gettimeofday(&start_time,NULL);
00393 #endif
00394 
00395         /* get the raw command line */
00396         get_raw_command_line_r(mac, svc->event_handler_ptr,svc->event_handler,&raw_command,macro_options);
00397         if(raw_command==NULL)
00398                 return ERROR;
00399 
00400         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Raw service event handler command line: %s\n",raw_command);
00401 
00402         /* process any macros in the raw command line */
00403         process_macros_r(mac, raw_command,&processed_command,macro_options);
00404         if(processed_command==NULL)
00405                 return ERROR;
00406 
00407         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Processed service event handler command line: %s\n",processed_command);
00408 
00409         if(log_event_handlers==TRUE){
00410                 dummy=asprintf(&raw_logentry,"SERVICE EVENT HANDLER: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n",svc->host_name,svc->description,svc->event_handler);
00411                 process_macros_r(mac, raw_logentry,&processed_logentry,macro_options);
00412                 logit(NSLOG_EVENT_HANDLER,FALSE,"%s",processed_logentry);
00413                 }
00414 
00415 #ifdef USE_EVENT_BROKER
00416         /* send event data to broker */
00417         end_time.tv_sec=0L;
00418         end_time.tv_usec=0L;
00419         neb_result=broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,svc->event_handler,processed_command,NULL,NULL);
00420 
00421         /* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
00422         if(neb_result==NEBERROR_CALLBACKOVERRIDE) {
00423                 my_free(processed_command);
00424                 my_free(raw_command);
00425                 my_free(raw_logentry);
00426                 my_free(processed_logentry);
00427                 return OK;
00428         }
00429 #endif
00430 
00431         /* run the command */
00432         result=my_system_r(mac, processed_command,event_handler_timeout,&early_timeout,&exectime,&command_output,0);
00433 
00434         /* check to see if the event handler timed out */
00435         if(early_timeout==TRUE)
00436                 logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE,"Warning: Service event handler command '%s' timed out after %d seconds\n",processed_command,event_handler_timeout);
00437 
00438 #ifdef USE_EVENT_BROKER
00439         /* get end time */
00440         gettimeofday(&end_time,NULL);
00441 #endif
00442 
00443 #ifdef USE_EVENT_BROKER
00444         /* send event data to broker */
00445         broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,svc->event_handler,processed_command,command_output,NULL);
00446 #endif
00447 
00448         /* free memory */
00449         my_free(command_output);
00450         my_free(raw_command);
00451         my_free(processed_command);
00452         my_free(raw_logentry);
00453         my_free(processed_logentry);
00454 
00455         return OK;
00456 }
00457 
00458 
00459 
00460 
00461 /******************************************************************/
00462 /****************** HOST EVENT HANDLER FUNCTIONS ******************/
00463 /******************************************************************/
00464 
00465 
00466 /* handles a change in the status of a host */
00467 int handle_host_event(host *hst){
00468         icinga_macros mac;
00469 
00470         log_debug_info(DEBUGL_FUNCTIONS,0,"handle_host_event()\n");
00471 
00472         if(hst==NULL)
00473                 return ERROR;
00474 
00475 #ifdef USE_EVENT_BROKER
00476         /* send event data to broker */
00477         broker_statechange_data(NEBTYPE_STATECHANGE_END,NEBFLAG_NONE,NEBATTR_NONE,HOST_STATECHANGE,(void *)hst,hst->current_state,hst->state_type,hst->current_attempt,hst->max_attempts,NULL);
00478 #endif
00479 
00480         /* bail out if we shouldn't be running event handlers */
00481         if(enable_event_handlers==FALSE)
00482                 return OK;
00483         if(hst->event_handler_enabled==FALSE)
00484                 return OK;
00485 
00486         /* update host macros */
00487         memset(&mac, 0, sizeof(mac));
00488         grab_host_macros_r(&mac, hst);
00489 
00490         /* run the global host event handler */
00491         run_global_host_event_handler(&mac, hst);
00492 
00493         /* run the event handler command if there is one */
00494         if(hst->event_handler!=NULL)
00495                 run_host_event_handler(&mac, hst);
00496 
00497         /* check for external commands - the event handler may have given us some directives... */
00498         check_for_external_commands();
00499 
00500         return OK;
00501 }
00502 
00503 
00504 /* runs the global host event handler */
00505 int run_global_host_event_handler(icinga_macros *mac, host *hst){
00506         char *raw_command=NULL;
00507         char *processed_command=NULL;
00508         char *raw_logentry=NULL;
00509         char *processed_logentry=NULL;
00510         char *command_output=NULL;
00511         int early_timeout=FALSE;
00512         double exectime=0.0;
00513         int result=0;
00514 #ifdef USE_EVENT_BROKER
00515         struct timeval start_time;
00516         struct timeval end_time;
00517         int neb_result=OK;
00518 #endif
00519         int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS;
00520 
00521 
00522         log_debug_info(DEBUGL_FUNCTIONS,0,"run_global_host_event_handler()\n");
00523 
00524         if(hst==NULL)
00525                 return ERROR;
00526 
00527         /* bail out if we shouldn't be running event handlers */
00528         if(enable_event_handlers==FALSE)
00529                 return OK;
00530 
00531         /* no global host event handler command is defined */
00532         if(global_host_event_handler==NULL)
00533                 return ERROR;
00534 
00535         log_debug_info(DEBUGL_EVENTHANDLERS,1,"Running global event handler for host '%s'..\n",hst->name);
00536 
00537 #ifdef USE_EVENT_BROKER
00538         /* get start time */
00539         gettimeofday(&start_time,NULL);
00540 #endif
00541 
00542         /* get the raw command line */
00543         get_raw_command_line_r(mac, global_host_event_handler_ptr,global_host_event_handler,&raw_command,macro_options);
00544         if(raw_command==NULL)
00545                 return ERROR;
00546 
00547         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Raw global host event handler command line: %s\n",raw_command);
00548 
00549         /* process any macros in the raw command line */
00550         process_macros_r(mac, raw_command,&processed_command,macro_options);
00551         if(processed_command==NULL)
00552                 return ERROR;
00553 
00554         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Processed global host event handler command line: %s\n",processed_command);
00555 
00556         if(log_event_handlers==TRUE){
00557                 dummy=asprintf(&raw_logentry,"GLOBAL HOST EVENT HANDLER: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n",hst->name,global_host_event_handler);
00558                 process_macros_r(mac, raw_logentry,&processed_logentry,macro_options);
00559                 logit(NSLOG_EVENT_HANDLER,FALSE,"%s",processed_logentry);
00560                 }
00561 
00562 #ifdef USE_EVENT_BROKER
00563         /* send event data to broker */
00564         end_time.tv_sec=0L;
00565         end_time.tv_usec=0L;
00566         neb_result=broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_host_event_handler,processed_command,NULL,NULL);
00567 
00568         /* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
00569         if(neb_result==NEBERROR_CALLBACKOVERRIDE) {
00570                 my_free(processed_command);
00571                 my_free(raw_command);
00572                 my_free(raw_logentry);
00573                 my_free(processed_logentry);
00574                 return OK;
00575         }
00576 #endif
00577 
00578         /* run the command */
00579         result=my_system_r(mac, processed_command,event_handler_timeout,&early_timeout,&exectime,&command_output,0);
00580 
00581         /* check for a timeout in the execution of the event handler command */
00582         if(early_timeout==TRUE)
00583                 logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE,"Warning: Global host event handler command '%s' timed out after %d seconds\n",processed_command,event_handler_timeout);
00584 
00585 #ifdef USE_EVENT_BROKER
00586         /* get end time */
00587         gettimeofday(&end_time,NULL);
00588 #endif
00589 
00590 #ifdef USE_EVENT_BROKER
00591         /* send event data to broker */
00592         broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_host_event_handler,processed_command,command_output,NULL);
00593 #endif
00594 
00595         /* free memory */
00596         my_free(command_output);
00597         my_free(raw_command);
00598         my_free(processed_command);
00599         my_free(raw_logentry);
00600         my_free(processed_logentry);
00601 
00602         return OK;
00603         }
00604 
00605 
00606 /* runs a host event handler command */
00607 int run_host_event_handler(icinga_macros *mac, host *hst){
00608         char *raw_command=NULL;
00609         char *processed_command=NULL;
00610         char *raw_logentry=NULL;
00611         char *processed_logentry=NULL;
00612         char *command_output=NULL;
00613         int early_timeout=FALSE;
00614         double exectime=0.0;
00615         int result=0;
00616 #ifdef USE_EVENT_BROKER
00617         struct timeval start_time;
00618         struct timeval end_time;
00619         int neb_result=OK;
00620 #endif
00621         int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS;
00622 
00623 
00624         log_debug_info(DEBUGL_FUNCTIONS,0,"run_host_event_handler()\n");
00625 
00626         if(hst==NULL)
00627                 return ERROR;
00628 
00629         /* bail if there's no command */
00630         if(hst->event_handler==NULL)
00631                 return ERROR;
00632 
00633         log_debug_info(DEBUGL_EVENTHANDLERS,1,"Running event handler for host '%s'..\n",hst->name);
00634 
00635 #ifdef USE_EVENT_BROKER
00636         /* get start time */
00637         gettimeofday(&start_time,NULL);
00638 #endif
00639 
00640         /* get the raw command line */
00641         get_raw_command_line_r(mac, hst->event_handler_ptr,hst->event_handler,&raw_command,macro_options);
00642         if(raw_command==NULL)
00643                 return ERROR;
00644 
00645         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Raw host event handler command line: %s\n",raw_command);
00646 
00647         /* process any macros in the raw command line */
00648         process_macros_r(mac, raw_command,&processed_command,macro_options);
00649         if(processed_command==NULL)
00650                 return ERROR;
00651 
00652         log_debug_info(DEBUGL_EVENTHANDLERS,2,"Processed host event handler command line: %s\n",processed_command);
00653 
00654         if(log_event_handlers==TRUE){
00655                 dummy=asprintf(&raw_logentry,"HOST EVENT HANDLER: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n",hst->name,hst->event_handler);
00656                 process_macros_r(mac, raw_logentry,&processed_logentry,macro_options);
00657                 logit(NSLOG_EVENT_HANDLER,FALSE,"%s",processed_logentry);
00658                 }
00659 
00660 #ifdef USE_EVENT_BROKER
00661         /* send event data to broker */
00662         end_time.tv_sec=0L;
00663         end_time.tv_usec=0L;
00664         neb_result=broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,hst->event_handler,processed_command,NULL,NULL);
00665 
00666         /* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
00667         if(neb_result==NEBERROR_CALLBACKOVERRIDE) {
00668                 my_free(processed_command);
00669                 my_free(raw_command);
00670                 my_free(raw_logentry);
00671                 my_free(processed_logentry);
00672                 return OK;
00673         }
00674 #endif
00675 
00676         /* run the command */
00677         result=my_system_r(mac, processed_command,event_handler_timeout,&early_timeout,&exectime,&command_output,0);
00678 
00679         /* check to see if the event handler timed out */
00680         if(early_timeout==TRUE)
00681                 logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE,"Warning: Host event handler command '%s' timed out after %d seconds\n",processed_command,event_handler_timeout);
00682 
00683 #ifdef USE_EVENT_BROKER
00684         /* get end time */
00685         gettimeofday(&end_time,NULL);
00686 #endif
00687 
00688 #ifdef USE_EVENT_BROKER
00689         /* send event data to broker */
00690         broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,hst->event_handler,processed_command,command_output,NULL);
00691 #endif
00692 
00693         /* free memory */
00694         my_free(command_output);
00695         my_free(raw_command);
00696         my_free(processed_command);
00697         my_free(raw_logentry);
00698         my_free(processed_logentry);
00699 
00700         return OK;
00701         }
00702 
00703 
00704 
00705 
00706 /******************************************************************/
00707 /****************** HOST STATE HANDLER FUNCTIONS ******************/
00708 /******************************************************************/
00709 
00710 
00711 /* top level host state handler - occurs after every host check (soft/hard and active/passive) */
00712 int handle_host_state(host *hst){
00713         int state_change=FALSE;
00714         time_t current_time=0L;
00715 
00716 
00717         log_debug_info(DEBUGL_FUNCTIONS,0,"handle_host_state()\n");
00718 
00719         /* get current time */
00720         time(&current_time);
00721 
00722         /* obsess over this host check */
00723         obsessive_compulsive_host_check_processor(hst);
00724 
00725         /* update performance data */
00726         update_host_performance_data(hst);
00727 
00728         /* record latest time for current state */
00729         switch(hst->current_state){
00730         case HOST_UP:
00731                 hst->last_time_up=current_time;
00732                 break;
00733         case HOST_DOWN:
00734                 hst->last_time_down=current_time;
00735                 break;
00736         case HOST_UNREACHABLE:
00737                 hst->last_time_unreachable=current_time;
00738                 break;
00739         default:
00740                 break;
00741                 }
00742 
00743         /* has the host state changed? */
00744         if(hst->last_state!=hst->current_state || hst->last_hard_state!=hst->current_state || (hst->current_state==HOST_UP && hst->state_type==SOFT_STATE))
00745                 state_change=TRUE;
00746 
00747         /* if the host state has changed... */
00748         if(state_change==TRUE){
00749 
00750                 /* update last state change times */
00751                 hst->last_state_change=current_time;
00752                 if(hst->state_type==HARD_STATE)
00753                         hst->last_hard_state_change=current_time;
00754 
00755                 /* update the event id */
00756                 hst->last_event_id=hst->current_event_id;
00757                 hst->current_event_id=next_event_id;
00758                 next_event_id++;
00759 
00760                 /* update the problem id when transitioning to a problem state */
00761                 if(hst->last_state==HOST_UP){
00762                         /* don't reset last problem id, or it will be zero the next time a problem is encountered */
00763                         /*hst->last_problem_id=hst->current_problem_id;*/
00764                         hst->current_problem_id=next_problem_id;
00765                         next_problem_id++;
00766                         }
00767 
00768                 /* clear the problem id when transitioning from a problem state to an UP state */
00769                 if(hst->current_state==HOST_UP){
00770                         hst->last_problem_id=hst->current_problem_id;
00771                         hst->current_problem_id=0L;
00772                         }
00773 
00774                 /* reset the acknowledgement flag if necessary */
00775                 if(hst->acknowledgement_type==ACKNOWLEDGEMENT_NORMAL){
00776 
00777                         hst->problem_has_been_acknowledged=FALSE;
00778                         hst->acknowledgement_type=ACKNOWLEDGEMENT_NONE;
00779 
00780                         /* remove any non-persistant comments associated with the ack */
00781                         delete_host_acknowledgement_comments(hst);
00782                         }
00783                 else if(hst->acknowledgement_type==ACKNOWLEDGEMENT_STICKY && hst->current_state==HOST_UP){
00784 
00785                         hst->problem_has_been_acknowledged=FALSE;
00786                         hst->acknowledgement_type=ACKNOWLEDGEMENT_NONE;
00787 
00788                         /* remove any non-persistant comments associated with the ack */
00789                         delete_host_acknowledgement_comments(hst);
00790                         }
00791 
00792                 /* reset the next and last notification times */
00793                 hst->last_host_notification=(time_t)0;
00794                 hst->next_host_notification=(time_t)0;
00795 
00796                 /* reset notification suppression option */
00797                 hst->no_more_notifications=FALSE;
00798 
00799                 /* write the host state change to the main log file */
00800                 if(hst->state_type==HARD_STATE || (hst->state_type==SOFT_STATE && log_host_retries==TRUE))
00801                         log_host_event(hst);
00802 
00803                 /* check for start of flexible (non-fixed) scheduled downtime in soft/hard states */
00804                 check_pending_flex_host_downtime(hst);
00805 
00806                 /* notify contacts about the recovery or problem if its a "hard" state */
00807                 if(hst->state_type==HARD_STATE){
00808 
00809 #ifdef USE_ST_BASED_ESCAL_RANGES
00810                         hst->current_down_notification_number=0;
00811                         hst->current_unreachable_notification_number=0;
00812 #endif
00813                         host_notification(hst,NOTIFICATION_NORMAL,NULL,NULL,NOTIFICATION_OPTION_NONE);
00814                 }
00815 
00816                 /* handle the host state change */
00817                 handle_host_event(hst);
00818 
00819                 /* the host just recovered, so reset the current host attempt */
00820                 if(hst->current_state==HOST_UP)
00821                         hst->current_attempt=1;
00822 
00823                 /* the host recovered, so reset the current notification number and state flags (after the recovery notification has gone out) */
00824                 if(hst->current_state==HOST_UP){
00825                         hst->current_notification_number=0;
00826                         hst->notified_on_down=FALSE;
00827                         hst->notified_on_unreachable=FALSE;
00828                         }
00829                 }
00830 
00831         /* else the host state has not changed */
00832         else{
00833 
00834                 /* notify contacts if host is still down or unreachable */
00835                 if(hst->current_state!=HOST_UP && hst->state_type==HARD_STATE)
00836                         host_notification(hst,NOTIFICATION_NORMAL,NULL,NULL,NOTIFICATION_OPTION_NONE);
00837 
00838                 /* if we're in a soft state and we should log host retries, do so now... */
00839                 if(hst->state_type==SOFT_STATE && log_host_retries==TRUE)
00840                         log_host_event(hst);
00841                 }
00842 
00843         return OK;
00844         }
00845 
00846 
 All Data Structures Files Functions Variables Typedefs Defines