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

check_procs.c

/*                                                                          
        Source: check_procs.c
        Author: Adam G. Bowen (agbowen@bealenet.com)
        $Revision: 1.4 $
        $Date: 1999/05/17 14:35:26 $
 
 * Program: Process check plugin for NetSaint
 * License: GPL
 * Copyright (c) 1999 Adam G. Bowen (agbowen@bealenet.com)
 *
 * Description:
 *
 * This plugin will check the number of processes running on the remote host at
 * ipaddress and generate an alert if number is above one of the threshold
 * values.
 *
 * Other errors result in a STATE_UNKNOWN return.
 *
 * Command line:
 *
 * check_procs ipaddress sys_type
 * check_procs ipaddress sys_type <state_flag>
 * check_procs ipaddress sys_type <warn_#> <crit_#>
 * check_procs ipaddress sys_type <warn_#> <crit_#> <state_flag>
 *
 * Required input:
 *
 * ipaddress = The ipaddress of the remote system to run the check on.
 * sys_type = The remote system type.
 *
 * Optional input:
 *
 * <warn_#> = Number of processes necessary to result in a WARNING state.
 * <crit_#> = Number of processes necessary to result in a CRITICAL state.
 * <state_flag> = Only report on processes in this state.
 *
 * Notes:
 *
 * If <warn_#>, <crit_#> and <state_flag> are not passed on the command line,
 * they will be set to the default values in the check_procs config file.
 *
 * If <warn_#> and <crit_#> are passed on the command line and <state_flag> is
 * not passed on the command line, <state_flag> is set to ALL.
 *
 * If <state_flag> is passed on the command line and <warn_#> and <crit_#> are
 * not passed on the command line, <warn_#> and <crit_#> are set to default
 * values in the check_procs config file.
 *
 * sys_type is used to determine which config file to use to generate the
 * remote command.
 *
 * The configuration file /usr/local/netsaint/config/check_procs/local
 * contains the following values:
 *
 * RSH_COMMAND|<location of rsh command on netsaint system>|
 * AWK_COMMAND|<location of awk command on netsaint system>|
 * WARN_PROCS|<default number of processes need to generate a warning>|
 * CRIT_PROCS|<default number of processes need to generate a critical>|
 *
 * The configuration file /usr/local/netsaint/config/check_procs/<sys_type>
 * contains the following values:
 *
 * PS_COMMAND|<location of ps command on system sys_type>|
 * PS_OPTIONS|<options for ps command to retreive required info>|
 * AWK_OPTIONS|<options for awk command to retreive required info>|
 * <flag name>|<flag on system sys_type>| * see below for explanation.
 *
 * Process state flags.
 *
 * All unix systems do not uses the same letter for the same state.  For 
 * example DEC osf1 use U for an Uninterruptible sleeping process.  However,
 * linux uses D for the same process.  In order for the process check to be
 * performed on heterogenious hosts, there had to be mapping of flags.  This
 * is accomplished by mapping the state flag passed on the command line to a
 * flag name.  Once the flag has been mapped to a name, the configuration file
 * /usr/local/netsaint/config/check_procs/<sys_type> will be searhed for an
 * entry containing <flag_name> and the <flag on system sys_type> will be 
 * mapped to state flag.
 *
 * The following list contains the command line flag and its' mapped flag_name:
 *
 * Command Line Flag | Flag Name
 *
 *      A            | ACTIVE
 *      C            | CANCELED
 *      H            | HALTED
 *      I            | IDLE
 *      O            | NON_EXISTANT
 *      P            | PROCESSING
 *      R            | RUNABLE
 *      S            | SLEEP
 *      T            | STOPPED
 *      U            | UNINT_SLEEP
 *      W            | SWAPPED
 *      Z            | ZOMBIE
 *
 * Note:
 * Not all systems will have all flags.
 *
 * $Log: check_procs.c,v $
 * Revision 1.4  1999/05/17 14:35:26  netsaint
 * Changed the plugin to use a seperate config directory.  This directory is the
 * CONFIG_DIR/command_name directory.
 *
 * Revision 1.3  1999/05/14 03:01:17  netsaint
 * Added the following integer variable:
 *    socket_name
 * Changed the call check_net to open_socket.  Added a call to recv_socket and
 * close_socket.  The check_net subroutine was changed to provide more
 * flexibility.
 * Added a call to the subroutine get_command_name.
 * Changed the error checking routines to ensure that any error cause the
 * program to terminate.
 *
 * Revision 1.2  1999/05/07 15:30:26  netsaint
 * Removed the char variable error_buffer and the FILE *error_fp variable.
 * These variables are no longer needed since the printing of the error file is
 * handled in a subroutine.
 * Added a call to the check_output_file subroutine.  This routine checks the
 * status of the output file.  Also removed the struct stat file_stat variable.
 * Added a call to the check_consistency subroutine.  This subroutine checks
 * that the warn value is less than the critical value.
 *
 * Revision 1.1  1999/05/03 20:23:16  netsaint
 * Initial revision
 *
*/

#include "/usr/local/src/netsaint/include/plugins.h"

int main(int argc, char *argv[])
{
  char expected[MAX_CHARS]="";
  char state_flag[MAX_CHARS]="";
  char state_label[MAX_CHARS]="All";

  char awk_command[MAX_CHARS];
  char awk_options[MAX_CHARS];
  char command_line[MAX_CHARS];
  char command_name[MAX_CHARS];
  char config_file_local[MAX_CHARS];
  char config_file_net[MAX_CHARS];
  char config_file_remote[MAX_CHARS];
  char error_file[MAX_CHARS];
  char input_buffer[MAX_CHARS];
  char ip_address[MAX_CHARS];
  char out_put_file[MAX_CHARS];
  char port_telnet[MAX_CHARS];
  char procs_crit[MAX_CHARS];
  char procs_warn[MAX_CHARS];
  char protocol[MAX_CHARS];
  char ps_command[MAX_CHARS];
  char ps_options[MAX_CHARS];
  char rsh_command[MAX_CHARS];
  char system_name[MAX_CHARS];
  char temp_value[MAX_CHARS];

  FILE *out_put_fp;

  int crit_procs;
  int get_all;
  int get_defaults;
  int process_count;
  int result;
  int return_value;
  int socket_name;
  int telnet_port;
  int warn_procs;

  /* Initialize alarm signal handling */

  signal(SIGALRM,alarm_signal);

  strcpy(command_name,get_command_name(argv[0]));
  if(!((argc==3) || (argc == 4) || (argc == 5) || (argc==6)))
  {
    printf("\n");
    printf(" Incorrect number of arguments supplied\n");
    printf("\n");
    printf(" Process check plugin for NetSaint\n");
    printf(" Copyright (c) 1999 Adam G. Bowen (agbowen@bealenet.com)\n");
    printf(" $Revision: 1.4 $\n");
    printf(" Last Modified $Date: 1999/05/17 14:35:26 $\n");
    printf(" License: GPL\n");
    printf("\n");
    printf(" Description:\n");
    printf("\n");
    printf(" This plugin will check the number of processes running on the remote host at\n");
    printf(" ipaddress and generate an alert if number is above one of the threshold\n");
    printf(" values.\n");
    printf("\n");
    printf(" Usage: %s ipaddress sys_type\n",command_name);
    printf(" Usage: %s ipaddress sys_type <state_flag>\n",command_name);
    printf(" Usage: %s ipaddress sys_type <warn_#> <crit_#>\n",command_name);
    printf(" Usage: %s ipaddress sys_type <warn_#> <crit_#> <state_flag>\n",command_name);
    printf("\n");
    printf(" Required input:\n");
    printf("\n");
    printf(" ipaddress = The ipaddress of the remote system to run the check on.\n");
    printf(" sys_type = The remote system type.\n");
    printf("\n");
    printf(" Optional input:\n");
    printf("\n");
    printf(" <warn_#> =Number of processes necessary to result in a WARNING state.\n");
    printf(" <crit_#> = Number of processes necessary to result in a CRITICAL state.\n");
    printf(" <state_flag> = Only report on processes in this state.\n");
    printf("\n");
    printf(" If <warn_#>, <crit_#> and <state_flag> are not passed on the command line,\n");
    printf(" they will be set to the default values in the %s config file.\n",command_name);
    printf("\n");
    printf(" If <warn_#> and <crit_#> are passed on the command line and <state_flag> is\n");
    printf(" not passed on the command line, <state_flag> is set to ALL.\n");
    printf("\n");
    printf("  If <state_flag> is passed on the command line and <warn_#> and <crit_#> are\n");
    printf(" not passed on the command line, <warn_#> and <crit_#> are set to default\n");
    printf(" values in the %s config file.\n", command_name);
    printf("\n");
    printf(" sys_type is used to determine which config file to use to generate the\n");
    printf(" remote command.\n");
    printf("\n");
    return_value = STATE_UNKNOWN;
  }
  else
  {
    /* Set up config files and get the command line information */

    strcpy(ip_address,argv[1]);
    strcpy(system_name,argv[2]);

    strcpy(config_file_local,CONFIG_DIR);
    strcpy(config_file_remote,CONFIG_DIR);
    strcpy(config_file_net,CONFIG_DIR);
    strcat(config_file_local,command_name);
    strcat(config_file_remote,command_name);
    strcat(config_file_net,CHECK_TELNET);
    strcat(config_file_local,"/local");
    strcat(config_file_remote,"/");
    strcat(config_file_net,"/");
    strcat(config_file_remote,system_name);
    strcat(config_file_net,system_name);

    if(argc == 3)
    {
      get_defaults = TRUE;
      get_all = TRUE;
    }
    else if(argc == 4)
    {
      get_defaults = TRUE;
      get_all = FALSE;
      strupr(strncpy(state_flag,argv[3],1));
    }
    else if(argc == 5)
    {
      get_defaults = FALSE;
      get_all = TRUE;
      strcpy(procs_warn,argv[3]);
      strcpy(procs_crit,argv[4]);
    }
    else
    {
      get_defaults = FALSE;
      get_all = FALSE;
      strcpy(procs_warn,argv[3]);
      strcpy(procs_crit,argv[4]);
      strupr(strncpy(state_flag,argv[5],1));
    }

    /* Check if config files exist */

    if (access(config_file_local, EXISTS) != 0 )
    {
      printf("Config file %s does not exist!\n",config_file_local);
      return_value = STATE_UNKNOWN;
    }
    else if (access(config_file_remote, EXISTS) != 0 )
    {
      printf("Config file %s does not exist!\n",config_file_remote);
      return_value = STATE_UNKNOWN;
    }
    else if (access(config_file_net, EXISTS) != 0 )
    {
      printf("Config file %s does not exist!\n",config_file_net);
      return_value = STATE_UNKNOWN;
    }
    else
    {
      if(!get_all)
      {
        if(strcmp(state_flag,"A") == 0)
        {
          strcpy(state_label,"Active");
          return_value=get_var("ACTIVE", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"C") == 0)
        {
          strcpy(state_label,"Canceled");
          return_value=get_var("CANCELED", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"H") == 0)
        {
          strcpy(state_label,"Halted");
          return_value=get_var("HALTED", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"I") == 0)
        {
          strcpy(state_label,"Idle");
          return_value=get_var("IDLE", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"O") == 0)
        {
          strcpy(state_label,"Non existant");
          return_value=get_var("NON_EXISTANT", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"P") == 0)
        {
          strcpy(state_label,"Processing");
          return_value=get_var("PROCESSING", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"R") == 0)
        {
          strcpy(state_label,"Runable");
          return_value=get_var("RUNABLE", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"S") == 0)
        {
          strcpy(state_label,"Sleep");
          return_value=get_var("SLEEP", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"T") == 0)
        {
          strcpy(state_label,"Stopped");
          return_value=get_var("STOPPED", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"U") == 0)
        {
          strcpy(state_label,"Uninterruptible Sleep");
          return_value=get_var("UNINT_SLEEP", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"W") == 0)
        {
          strcpy(state_label,"Swapped");
          return_value=get_var("SWAPPED", config_file_remote, temp_value);
        }
        else if(strcmp(state_flag,"Z") == 0)
        {
          strcpy(state_label,"Zombie");
          return_value=get_var("ZOMBIE", config_file_remote, temp_value);
        }
        else
        {
          printf("%s is an unknow state flag.\n",state_flag);
          return_value = STATE_UNKNOWN;
        }
        if(strcmp(temp_value, "NOT_FOUND") == 0)
        {
          printf("%s state information not found in config file %s!\n",state_label, config_file_remote);
          return_value = STATE_UNKNOWN;
        } 
        else
        {
          strcpy(state_flag,temp_value);
        }
      }
      else
      {
        return_value = STATE_OK;
      }
      if(return_value == STATE_OK)
      {

        /* Local config file variables */

        if((get_defaults == TRUE) && ((return_value=get_var("WARN_PROCS", config_file_local, procs_warn)) != STATE_OK))
        {
          printf("WARN_PROCS entry not found in config file %s!\n",config_file_local);
        }
        else if((get_defaults == TRUE) && ((return_value=get_var("CRIT_PROCS", config_file_local, procs_crit)) != STATE_OK))
        {
          printf("CRIT_PROCS entry not found in config file %s!\n",config_file_local);
        }
        else if((return_value=get_var("RSH_COMMAND", config_file_local, rsh_command)) != STATE_OK)
        {
          printf("RSH_COMMAND entry not found in config file %s!\n", config_file_local);
        }
        else if((return_value=get_var("AWK_COMMAND", config_file_local, awk_command)) != STATE_OK)
        {
          printf("AWK_COMMAND entry not found in config file %s!\n", config_file_local);
        }

        /* Remote config file variables */

        else if((return_value=get_var("PS_COMMAND", config_file_remote, ps_command)) != STATE_OK)
        {
          printf("PS_COMMAND entry not found in config file %s!\n", config_file_remote);
        }
        else if((return_value=get_var("PS_OPTIONS", config_file_remote, ps_options)) != STATE_OK)
        {
          printf("PS_OPTIONS entry not found in config file %s!\n",config_file_remote);
        }
        else if((return_value=get_var("AWK_OPTIONS", config_file_remote, awk_options)) != STATE_OK)
        {
          printf("AWK_OPTIONS entry not found in config file %s!\n",config_file_remote);
        }

        /* Network config file variables */

        else if((return_value=get_var("TELNET_PORT", config_file_net, port_telnet)) != STATE_OK)
        {
          printf("TELNET_PORT entry not found in config file %s!\n",config_file_net);
        }
        else if((return_value=get_var("TELNET_PROTO", config_file_net, protocol)) != STATE_OK)
        {
          printf("TELNET_PROTO entry not found in config file %s!\n",config_file_net);
        }
        else
        {
  
          /* Check alert level consistency */

          warn_procs=atoi(procs_warn);
          crit_procs=atoi(procs_crit);
          return_value = check_consistency(warn_procs, crit_procs);
          if(return_value == STATE_OK)
          {

            /* Check the network */

            telnet_port=atoi(port_telnet);
            alarm(TIME_OUT);
            if((result=open_socket(&socket_name, ip_address, telnet_port, protocol)) != STATE_OK)
            {
              return_value=exit_error(result,ip_address,protocol,telnet_port);
            }
            else if((result=recv_socket(&socket_name, expected)) != STATE_OK)
            {
              return_value=exit_error(result,ip_address,protocol,telnet_port);
            }
            else if((result=close_socket(&socket_name)) != STATE_OK)
            {
              return_value=exit_error(result,ip_address,protocol,telnet_port);
            }
            else
            {
              alarm(0);

              /* Generate a out_put and error file names */
  
              strcpy(out_put_file, tmpnam(NULL));
              strcpy(error_file, tmpnam(NULL));
   
              /* Set the command line and arguments to use for the check */
  
              sprintf(command_line,"%s %s %s %s </dev/null 2>%s|%s %s >%s 2>>%s",rsh_command, ip_address, ps_command, ps_options, error_file, awk_command, awk_options, out_put_file, error_file);
  
              /* Run the command */
    
              system(command_line);
  
              return_value=check_output_file(out_put_file);
              if (return_value != STATE_OK)
              {
                print_error(error_file);
              }
              else
              {
                out_put_fp=fopen(out_put_file,"r");
  
                /* Retrive single line from output file */
  
                fgets(input_buffer,MAX_CHARS-1,out_put_fp);
                process_count = 0;
  
                while(fgets(input_buffer,MAX_CHARS-1,out_put_fp) != NULL)
                {
                  if(get_all)
                  {
                    process_count++;
                  }
                  else if(strstr(input_buffer,state_flag) !=0)
                  {
                    process_count++;
                  }
                }
  
                /* Close output file */
  
                fclose(out_put_fp);
    
                /* Check the process count against warning and critical levels */
    
                if(process_count >= crit_procs)
                {
                  return_value=STATE_CRITICAL;
                }
                else if(process_count >= warn_procs)
                {
                  return_value=STATE_WARNING;
                }
      
                if(return_value==STATE_OK)
                {
                  printf("%s processes count ok - %d processes in %s state\n", state_label,process_count,state_label);
                }
                else
                {
                  printf("%s processes count error - %d processes in %s state\n", state_label,process_count,state_label);
                }
              }
    
              /* Remove the output and error files */
    
              remove(out_put_file);
              remove(error_file);
  
            }
          }
        }
      }
    }
  }
  return return_value;
}

Generated by  Doxygen 1.6.0   Back to index