Logo Search packages:      
Sourcecode: nagios version File versions  Download package

sehandlers.c

/*****************************************************************************
 *
 * SEHANDLERS.C - Service and host event and state handlers for Nagios
 *
 * Copyright (c) 1999-2003 Ethan Galstad (nagios@nagios.org)
 * Last Modified:   12-04-2003
 *
 * License:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 "../common/config.h"
#include "../common/common.h"
#include "../common/statusdata.h"
#include "../common/downtime.h"
#include "nagios.h"


extern int             enable_event_handlers;
extern int             obsess_over_services;

extern int             log_event_handlers;
extern int             log_host_retries;

extern int             event_handler_timeout;
extern int             ocsp_timeout;

extern char            *macro_current_service_attempt;
extern char            *macro_current_host_attempt;
extern char            *macro_host_state;
extern char        *macro_service_state;
extern char            *macro_state_type;

extern char            *global_host_event_handler;
extern char            *global_service_event_handler;

extern char            *ocsp_command;

extern time_t          program_start;



/******************************************************************/
/******** OBSESSIVE COMPULSIVE SERVICE HANDLER FUNCTIONS **********/
/******************************************************************/


/* handles service check results in an obsessive compulsive manner... */
int obsessive_compulsive_service_check_processor(service *svc,int state_type){
      char raw_command_line[MAX_INPUT_BUFFER];
      char processed_command_line[MAX_INPUT_BUFFER];
      char temp_buffer[MAX_INPUT_BUFFER];
      command *temp_command;
      host *temp_host;
      int early_timeout=FALSE;

#ifdef DEBUG0
      printf("obsessive_compulsive_service_check_processor() start\n");
#endif

      /* bail out if we shouldn't be obsessing */
      if(obsess_over_services==FALSE)
            return OK;
      if(svc->obsess_over_service==FALSE)
            return OK;

      /* find the associated host */
      temp_host=find_host(svc->host_name,NULL);

      /* update service macros */
      clear_volatile_macros();
      grab_host_macros(temp_host);
      grab_service_macros(svc);

      /* grab the service state type macro */
      if(macro_state_type!=NULL)
            free(macro_state_type);
      macro_state_type=(char *)malloc(MAX_STATETYPE_LENGTH);
      if(macro_state_type!=NULL)
            strcpy(macro_state_type,(state_type==HARD_STATE)?"HARD":"SOFT");

      /* grab the current service check number macro */
      if(macro_current_service_attempt!=NULL)
            free(macro_current_service_attempt);
      macro_current_service_attempt=(char *)malloc(MAX_ATTEMPT_LENGTH);
      if(macro_current_service_attempt!=NULL)
            sprintf(macro_current_service_attempt,"%d",svc->current_attempt);

      /* find the service processor command */
      temp_command=find_command(ocsp_command,NULL);

      /* if there is no valid command, exit */
      if(temp_command==NULL)
            return ERROR;

      /* get the raw command line to execute */
      strncpy(raw_command_line,temp_command->command_line,sizeof(raw_command_line));
      raw_command_line[sizeof(raw_command_line)-1]='\x0';

#ifdef DEBUG3
      printf("\tRaw obsessive compulsive service processor command line: %s\n",raw_command_line);
#endif

      /* process any macros in the raw command line */
      process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS);

#ifdef DEBUG3
      printf("\tProcessed obsessive compulsive service processor command line: %s\n",processed_command_line);
#endif

      /* run the command */
      my_system(processed_command_line,ocsp_timeout,&early_timeout,NULL,0);

      /* check to see if the command timed out */
      if(early_timeout==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"Warning: OCSP command '%s' for service '%s' on host '%s' timed out after %d seconds\n",ocsp_command,svc->description,svc->host_name,ocsp_timeout);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE);
              }
      
#ifdef DEBUG0
      printf("obsessive_compulsive_service_check_processor() end\n");
#endif

      return OK;
        }





/******************************************************************/
/**************** SERVICE EVENT HANDLER FUNCTIONS *****************/
/******************************************************************/


/* handles changes in the state of a service */
int handle_service_event(service *svc,int state_type){
      command *event_command;
      host *temp_host;

#ifdef DEBUG0
      printf("handle_service_event() start\n");
#endif

      /* bail out if we shouldn't be running event handlers */
      if(enable_event_handlers==FALSE)
            return OK;
      if(svc->event_handler_enabled==FALSE)
            return OK;

      /* find the host */
      temp_host=find_host(svc->host_name,NULL);

      /* update service macros */
      clear_volatile_macros();
      grab_host_macros(temp_host);
      grab_service_macros(svc);

      /* grab the service state type macro */
      if(macro_state_type!=NULL)
            free(macro_state_type);
      macro_state_type=(char *)malloc(MAX_STATETYPE_LENGTH);
      if(macro_state_type!=NULL)
            strcpy(macro_state_type,(state_type==HARD_STATE)?"HARD":"SOFT");

      /* grab the current service check number macro */
      if(macro_current_service_attempt!=NULL)
            free(macro_current_service_attempt);
      macro_current_service_attempt=(char *)malloc(MAX_ATTEMPT_LENGTH);
      if(macro_current_service_attempt!=NULL)
            sprintf(macro_current_service_attempt,"%d",svc->current_attempt);

      /* run the global service event handler */
      run_global_service_event_handler(svc,state_type);

      /* find the service event handler command if there is one */
      if(svc->event_handler==NULL)
            event_command=NULL;
      else
            event_command=find_command(svc->event_handler,NULL);

      /* run the event handler command if there is one */
      if(event_command!=NULL)
            run_service_event_handler(svc,event_command,state_type);

      /* check for external commands - the event handler may have given us some directives... */
      check_for_external_commands();

#ifdef DEBUG0
      printf("handle_service_event() end\n");
#endif

      return OK;
        }



/* runs the global service event handler */
int run_global_service_event_handler(service *svc,int state_type){
      char raw_command_line[MAX_INPUT_BUFFER];
      char processed_command_line[MAX_INPUT_BUFFER];
      char temp_buffer[MAX_INPUT_BUFFER];
      command *temp_command;
      int early_timeout=FALSE;

#ifdef DEBUG0
      printf("run_global_service_event_handler() start\n");
#endif

      /* bail out if we shouldn't be running event handlers */
      if(enable_event_handlers==FALSE)
            return OK;

      /* a global service event handler command has not been defined */
      if(global_service_event_handler==NULL)
            return ERROR;

      /* find the event handler command */
      temp_command=find_command(global_service_event_handler,NULL);

      /* if there is no valid command, exit */
      if(temp_command==NULL)
            return ERROR;

      /* get the raw command line to execute */
      strncpy(raw_command_line,temp_command->command_line,sizeof(raw_command_line));
      raw_command_line[sizeof(raw_command_line)-1]='\x0';

#ifdef DEBUG3
      printf("\tRaw global service event handler command line: %s\n",raw_command_line);
#endif

      /* process any macros in the raw command line */
      process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS);

#ifdef DEBUG3
      printf("\tProcessed global service event handler command line: %s\n",processed_command_line);
#endif

      if(log_event_handlers==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"GLOBAL SERVICE EVENT HANDLER: %s;%s;%s;%s;%s;%s\n",svc->host_name,svc->description,macro_service_state,macro_state_type,macro_current_service_attempt,global_service_event_handler);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER,FALSE);
              }

      /* run the command */
      my_system(processed_command_line,event_handler_timeout,&early_timeout,NULL,0);

      /* check to see if the event handler timed out */
      if(early_timeout==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Global service event handler command '%s' timed out after %d seconds\n",global_service_event_handler,event_handler_timeout);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE);
              }

#ifdef DEBUG0
      printf("run_global_service_event_handler() end\n");
#endif

      return OK;
        }



/* runs a service event handler command */
int run_service_event_handler(service *svc,command *cmd,int state_type){
      char raw_command_line[MAX_INPUT_BUFFER];
      char processed_command_line[MAX_INPUT_BUFFER];
      char temp_buffer[MAX_INPUT_BUFFER];
      int early_timeout=FALSE;

#ifdef DEBUG0
      printf("run_service_event_handler() start\n");
#endif

      /* get the raw command line to execute */
      strncpy(raw_command_line,cmd->command_line,sizeof(raw_command_line));
      raw_command_line[sizeof(raw_command_line)-1]='\x0';

#ifdef DEBUG3
      printf("\tRaw service event handler command line: %s\n",raw_command_line);
#endif

      /* process any macros in the raw command line */
      process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS);

#ifdef DEBUG3
      printf("\tProcessed service event handler command line: %s\n",processed_command_line);
#endif

      if(log_event_handlers==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE EVENT HANDLER: %s;%s;%s;%s;%s;%s\n",svc->host_name,svc->description,macro_service_state,macro_state_type,macro_current_service_attempt,svc->event_handler);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER,FALSE);
              }

      /* run the command */
      my_system(processed_command_line,event_handler_timeout,&early_timeout,NULL,0);

      /* check to see if the event handler timed out */
      if(early_timeout==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service event handler command '%s' timed out after %d seconds\n",svc->event_handler,event_handler_timeout);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE);
              }
#ifdef DEBUG0
      printf("run_service_event_handler() end\n");
#endif

      return OK;
        }




/******************************************************************/
/****************** HOST EVENT HANDLER FUNCTIONS ******************/
/******************************************************************/


/* handles a change in the status of a host */
int handle_host_event(host *hst,int state,int state_type){
      command *event_command;

#ifdef DEBUG0
      printf("handle_host_event() start\n");
#endif

      /* bail out if we shouldn't be running event handlers */
      if(enable_event_handlers==FALSE)
            return OK;
      if(hst->event_handler_enabled==FALSE)
            return OK;

      /* update host macros */
      grab_host_macros(hst);

      /* grab the host state type macro */
      if(macro_state_type!=NULL)
            free(macro_state_type);
      macro_state_type=(char *)malloc(MAX_STATETYPE_LENGTH);
      if(macro_state_type!=NULL)
            strcpy(macro_state_type,(state_type==HARD_STATE)?"HARD":"SOFT");

      /* make sure the host state macro is correct */
      if(macro_host_state!=NULL)
            free(macro_host_state);
      macro_host_state=(char *)malloc(MAX_STATE_LENGTH);
      if(macro_host_state!=NULL){
            if(state==HOST_DOWN)
                  strcpy(macro_host_state,"DOWN");
            else if(state==HOST_UNREACHABLE)
                  strcpy(macro_host_state,"UNREACHABLE");
            else
                  strcpy(macro_host_state,"UP");
              }

      /* run the global host event handler */
      run_global_host_event_handler(hst,state,state_type);

      /* find the host event handler command */
      if(hst->event_handler==NULL)
            event_command=NULL;
      else
            event_command=find_command(hst->event_handler,NULL);

      /* run the event handler command if there is one */
      if(event_command!=NULL)
            run_host_event_handler(hst,event_command,state,state_type);

      /* check for external commands - the event handler may have given us some directives... */
      check_for_external_commands();

#ifdef DEBUG0
      printf("handle_host_event() end\n");
#endif

      return OK;
        }


/* runs the global host event handler */
int run_global_host_event_handler(host *hst,int state,int state_type){
      char raw_command_line[MAX_INPUT_BUFFER];
      char processed_command_line[MAX_INPUT_BUFFER];
      char temp_buffer[MAX_INPUT_BUFFER];
      command *temp_command;
      int early_timeout=FALSE;

#ifdef DEBUG0
      printf("run_global_host_event_handler() start\n");
#endif

      /* bail out if we shouldn't be running event handlers */
      if(enable_event_handlers==FALSE)
            return OK;

      /* no global host event handler command is defined */
      if(global_host_event_handler==NULL)
            return ERROR;

      /* find the event handler command */
      temp_command=find_command(global_host_event_handler,NULL);

      /* if there is no valid event handler command, exit */
      if(temp_command==NULL)
            return ERROR;

      /* get the raw command line to execute */
      strncpy(raw_command_line,temp_command->command_line,sizeof(raw_command_line)-1);
      raw_command_line[sizeof(raw_command_line)-1]='\x0';

#ifdef DEBUG3
      printf("\tRaw global host event handler command line: %s\n",raw_command_line);
#endif

      /* process any macros in the raw command line */
      process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS);

#ifdef DEBUG3
      printf("\tProcessed global host event handler command line: %s\n",processed_command_line);
#endif

      if(log_event_handlers==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"GLOBAL HOST EVENT HANDLER: %s;%s;%s;%s;%s\n",hst->name,macro_host_state,macro_state_type,macro_current_host_attempt,global_host_event_handler);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER,FALSE);
              }

      /* run the command */
      my_system(processed_command_line,event_handler_timeout,&early_timeout,NULL,0);

      /* check for a timeout in the execution of the event handler command */
      if(early_timeout==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Global host event handler command '%s' timed out after %d seconds\n",global_host_event_handler,event_handler_timeout);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE);
              }

#ifdef DEBUG0
      printf("run_global_host_event_handler() end\n");
#endif

      return OK;
        }


/* runs a host event handler command */
int run_host_event_handler(host *hst,command *cmd,int state,int state_type){
      char raw_command_line[MAX_INPUT_BUFFER];
      char processed_command_line[MAX_INPUT_BUFFER];
      char temp_buffer[MAX_INPUT_BUFFER];
      int early_timeout=FALSE;

#ifdef DEBUG0
      printf("run_host_event_handler() start\n");
#endif

      /* get the raw command line to execute */
      strncpy(raw_command_line,cmd->command_line,sizeof(raw_command_line)-1);
      raw_command_line[sizeof(raw_command_line)-1]='\x0';

#ifdef DEBUG3
      printf("\tRaw host event handler command line: %s\n",raw_command_line);
#endif

      /* process any macros in the raw command line */
      process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS);

#ifdef DEBUG3
      printf("\tProcessed host event handler command line: %s\n",processed_command_line);
#endif

      if(log_event_handlers==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"HOST EVENT HANDLER: %s;%s;%s;%s;%s\n",hst->name,macro_host_state,macro_state_type,macro_current_host_attempt,hst->event_handler);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER,FALSE);
              }

      /* run the command */
      my_system(processed_command_line,event_handler_timeout,&early_timeout,NULL,0);

      /* check to see if the event handler timed out */
      if(early_timeout==TRUE){
            snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Host event handler command '%s' timed out after %d seconds\n",hst->event_handler,event_handler_timeout);
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE);
              }
#ifdef DEBUG0
      printf("run_host_event_handler() end\n");
#endif

      return OK;
        }




/******************************************************************/
/**************** SERVICE STATE HANDLER FUNCTIONS *****************/
/******************************************************************/


/* updates service state times */
void update_service_state_times(service *svc){
      unsigned long time_difference;
      time_t current_time;

#ifdef DEBUG0
      printf("update_service_state_times() start\n");
#endif

      /* calculate the time since the last service state change */
      time(&current_time);

      /* if this is NOT the first time we've had a service check/state change.. */
      if(svc->has_been_checked==TRUE){

            if(svc->last_state_change<program_start)
                  time_difference=(unsigned long)current_time-program_start;
            else
                  time_difference=(unsigned long)current_time-svc->last_state_change;

            /* use last hard state... */
            if(svc->last_hard_state==STATE_UNKNOWN)
                  svc->time_unknown+=time_difference;
            else if(svc->last_hard_state==STATE_WARNING)
                  svc->time_warning+=time_difference;
            else if(svc->last_hard_state==STATE_CRITICAL)
                  svc->time_critical+=time_difference;
            else
                  svc->time_ok+=time_difference;
              }


      /* update the last service state change time */
      svc->last_state_change=current_time;

      /* update status log with service information */
      update_service_status(svc,FALSE);


#ifdef DEBUG0
      printf("update_service_state_times() end\n");
#endif
      
      return;
        }




/******************************************************************/
/****************** HOST STATE HANDLER FUNCTIONS ******************/
/******************************************************************/


/* top level host state handler */
int handle_host_state(host *hst,int state,int state_type){
      int state_change=FALSE;

#ifdef DEBUG0
      printf("handle_host_state() start\n");
#endif


      /* has the host state changed? */
      if(hst->status!=state)
            state_change=TRUE;

      /* if the host state has changed... */
      if(state_change==TRUE){

            /* reset the acknowledgement flag */
            hst->problem_has_been_acknowledged=FALSE;

            /* reset the next and last notification times */
            hst->last_host_notification=(time_t)0;
            hst->next_host_notification=(time_t)0;

            /* reset notification supression option */
            hst->no_more_notifications=FALSE;

            /* set the state flags in case we "float" between down and unreachable states before a recovery */
            if(state_type==HARD_STATE){
                  if(state==HOST_DOWN)
                        hst->has_been_down=TRUE;
                  else if(state==HOST_UNREACHABLE)
                        hst->has_been_unreachable=TRUE;
                    }

            /* update the host state times */
            if(state_type==HARD_STATE)
                  update_host_state_times(hst);

            /* the host just recovered, so reset the current host attempt number */
            if(state==HOST_UP)
                  hst->current_attempt=1;

            /* write the host state change to the main log file */
            if(state_type==HARD_STATE || (state_type==SOFT_STATE && log_host_retries==TRUE))
                  log_host_event(hst,state,state_type);

            /* check for start of flexible (non-fixed) scheduled downtime */
            /*if(state_type==HARD_STATE && hst->pending_flex_downtime>0)*/
            if(state_type==HARD_STATE)
                  check_pending_flex_host_downtime(hst,state);

            /* notify contacts about the recovery or problem if its a "hard" state */
            if(state_type==HARD_STATE)
                  host_notification(hst,state,NULL);

            /* handle the host state change */
            handle_host_event(hst,state,state_type);

            /* the host recovered, so reset the current notification number and state flags (after the recovery notification has gone out) */
            if(state==HOST_UP){
                  hst->current_notification_number=0;
                  hst->has_been_down=FALSE;
                  hst->has_been_unreachable=FALSE;
                    }

            /* set the host state flag and update the status log if this is a hard state */
            if(state_type==HARD_STATE){
                  hst->status=state;
                  update_host_status(hst,FALSE);
                    }
              }

      /* else the host state has not changed */
      else{

            /* notify contacts if host is still down */
            if(state!=HOST_UP && state_type==HARD_STATE)
                  host_notification(hst,state,NULL);

            /* if we're in a soft state and we should log host retries, do so now... */
            if(state_type==SOFT_STATE && log_host_retries==TRUE)
                  log_host_event(hst,state,state_type);

            /* update the status log if this is a hard state */
            if(state_type==HARD_STATE)
                  update_host_status(hst,FALSE);

              }

#ifdef DEBUG0
      printf("handle_host_state() end\n");
#endif

      return OK;
        }




/* updates host state times */
void update_host_state_times(host *hst){
      unsigned long time_difference;
      time_t current_time;

#ifdef DEBUG0
      printf("update_host_state_times() start\n");
#endif

      /* get the current time */
      time(&current_time);

      /* if this is NOT the first time we've had a host check/state change... */
      if(hst->has_been_checked==TRUE){

            if(hst->last_state_change<program_start)
                  time_difference=(unsigned long)current_time-program_start;
            else
                  time_difference=(unsigned long)current_time-hst->last_state_change;

            if(hst->status==HOST_DOWN)
                  hst->time_down+=time_difference;
            else if(hst->status==HOST_UNREACHABLE)
                  hst->time_unreachable+=time_difference;
            else
                  hst->time_up+=time_difference;
              }

      /* update the last host state change time */
      hst->last_state_change=current_time;

      /* update status log with host information */
      update_host_status(hst,FALSE);


#ifdef DEBUG0
      printf("update_host_state_times() end\n");
#endif
      
      return;
        }


Generated by  Doxygen 1.6.0   Back to index