Back to index

nagios-plugins  1.4.16
check_cluster.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * CHECK_CLUSTER.C - Host and Service Cluster Plugin for NetSaint
00004  *
00005  * Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org)
00006  * License: GPL
00007  * Last Modified:   07-08-2000
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 as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00024  *
00025  *****************************************************************************/
00026 
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 
00031 #define OK           0
00032 #define ERROR        -1
00033 
00034 #define TRUE         1
00035 #define FALSE        0
00036 
00037 #define CHECK_SERVICES      1
00038 #define CHECK_HOSTS  2
00039 
00040 #define MAX_INPUT_BUFFER    1024
00041 
00042 #define STATE_OK     0
00043 #define STATE_WARNING       1
00044 #define STATE_CRITICAL      2
00045 #define STATE_UNKNOWN       3
00046 
00047 typedef struct clustermember_struct{
00048        char *host_name;
00049        char *svc_description;
00050        struct clustermember_struct *next;
00051         }clustermember;
00052 
00053 
00054 int check_cluster_status(void);
00055 int add_clustermember(char *,char *);
00056 void free_memory(void);
00057 
00058 clustermember *clustermember_list=NULL;
00059 
00060 int total_services_ok=0;
00061 int total_services_warning=0;
00062 int total_services_unknown=0;
00063 int total_services_critical=0;
00064 
00065 int total_hosts_up=0;
00066 int total_hosts_down=0;
00067 int total_hosts_unreachable=0;
00068 
00069 char status_log[MAX_INPUT_BUFFER]="";
00070 int warning_threshold=0;
00071 int critical_threshold=0;
00072 
00073 int check_type=CHECK_SERVICES;
00074 
00075 
00076 int main(int argc, char **argv){
00077        char input_buffer[MAX_INPUT_BUFFER];
00078        char *host_name;
00079        char *svc_description;
00080        int return_code=STATE_OK;
00081        int error=FALSE;
00082 
00083        if(argc!=5){
00084 
00085               printf("Invalid arguments supplied\n");
00086               printf("\n");
00087 
00088               printf("Host/Service Cluster Plugin for NetSaint\n");
00089               printf("Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org)\n");
00090               printf("Last Modified: 07-08-2000\n");
00091               printf("License: GPL\n");
00092               printf("\n");
00093               printf("Usage: %s <--service | --host> <status_log> <warn_threshold> <crit_threshold>\n",argv[0]);
00094               printf("\n");
00095               printf("Options:\n");
00096               printf("   --service        = Check service cluster status\n");
00097               printf("   --host           = Check host cluster status\n");
00098               printf("   <status_log>     = This is the location of the NetSaint status log\n");
00099               printf("   <warn_threshold> = This is the number of hosts or services in\n");
00100               printf("                      the cluster that must be in a non-OK state\n");
00101               printf("                      in order to result in a warning status level\n");
00102               printf("   <crit_threshold> = This is the number of hosts or services in\n");
00103               printf("                      the cluster that must be in a non-OK state\n");
00104               printf("                      in order to result in a critical status level\n");
00105               printf("\n");
00106               printf("Notes:\n");
00107               printf("Members of the host or service cluster are read from STDIN.\n");
00108               printf("One host or service can be specified per line, services must\n");
00109               printf("be in the format of <host_name>;<svc_description>\n");
00110               printf("\n");
00111 
00112               return STATE_UNKNOWN;
00113                }
00114 
00115        /* see if we're checking a host or service clust */
00116        if(!strcmp(argv[1],"--host"))
00117               check_type=CHECK_HOSTS;
00118        else
00119               check_type=CHECK_SERVICES;
00120 
00121        /* get the status log */
00122        strncpy(status_log,argv[2],sizeof(status_log)-1);
00123        status_log[sizeof(status_log)-1]='\x0';
00124 
00125        /* get the warning and critical thresholds */
00126        warning_threshold=atoi(argv[3]);
00127        critical_threshold=atoi(argv[4]);
00128 
00129 
00130        /* read all data from STDIN until there isn't anymore */
00131        while(fgets(input_buffer,sizeof(input_buffer)-1,stdin)){
00132 
00133               if(feof(stdin))
00134                      break;
00135 
00136               /*strip(input_buffer);*/
00137 
00138               if(!strcmp(input_buffer,""))
00139                      continue;
00140 
00141               if(!strcmp(input_buffer,"\n"))
00142                      continue;
00143 
00144               /* get the host name */
00145               if(check_type==CHECK_SERVICES)
00146                      host_name=(char *)strtok(input_buffer,";");
00147               else
00148                      host_name=(char *)strtok(input_buffer,"\n");
00149               if(host_name==NULL || !strcmp(host_name,"")){
00150                      printf("Error: Host name is NULL!\n");
00151                      continue;
00152                       }
00153 
00154               if(check_type==CHECK_SERVICES){
00155 
00156                      /* get the service description */
00157                      svc_description=(char *)strtok(NULL,"\n");
00158                      if(svc_description==NULL || !strcmp(svc_description,"")){
00159                             printf("Error: Service description is NULL!\n");
00160                             continue;
00161                              }
00162                       }
00163 
00164               /* add the cluster member to the list in memory */
00165               if(add_clustermember(host_name,svc_description)!=OK)
00166                      printf("Error: Could not add cluster member\n");
00167 #ifdef DEBUG
00168               else
00169                      printf("Added cluster member\n");
00170 #endif
00171                }
00172 
00173 
00174        /* check the status of the cluster */
00175        if(check_cluster_status()==OK){
00176        
00177               if(check_type==CHECK_SERVICES){
00178                      if((total_services_warning+total_services_unknown+total_services_critical) >= critical_threshold)
00179                             return_code=STATE_CRITICAL;
00180                      else if((total_services_warning+total_services_unknown+total_services_critical) >= warning_threshold)
00181                             return_code=STATE_WARNING;
00182                      else
00183                             return_code=STATE_OK;
00184               
00185                      printf("Service cluster %s: %d ok, %d warning, %d unknown, %d critical\n",(return_code==STATE_OK)?"ok":"problem",total_services_ok,total_services_warning,total_services_unknown,total_services_critical);
00186                        }
00187               else{
00188                      if((total_hosts_down+total_hosts_unreachable) >= critical_threshold)
00189                             return_code=STATE_CRITICAL;
00190                      else if((total_hosts_down+total_hosts_unreachable) >= warning_threshold)
00191                             return_code=STATE_WARNING;
00192                      else
00193                             return_code=STATE_OK;
00194 
00195                      printf("Host cluster %s: %d up, %d down, %d unreachable\n",(return_code==STATE_OK)?"ok":"problem",total_hosts_up,total_hosts_down,total_hosts_unreachable);
00196                        }
00197                }
00198        else
00199               return_code=STATE_UNKNOWN;
00200 
00201        free_memory();
00202 
00203        return return_code;
00204         }
00205 
00206 
00207 
00208 int add_clustermember(char *hst,char *svc){
00209        clustermember *new_clustermember;
00210 
00211        new_clustermember=(clustermember *)malloc(sizeof(clustermember));
00212        if(new_clustermember==NULL)
00213               return ERROR;
00214 
00215        new_clustermember->host_name=NULL;
00216        new_clustermember->svc_description=NULL;
00217 
00218        if(hst!=NULL){
00219               new_clustermember->host_name=(char *)malloc(strlen(hst)+1);
00220               if(new_clustermember->host_name==NULL){
00221                      free(new_clustermember);
00222                      return ERROR;
00223                       }
00224               strcpy(new_clustermember->host_name,hst);
00225                }
00226 
00227        if(svc!=NULL){
00228               new_clustermember->svc_description=(char *)malloc(strlen(svc)+1);
00229               if(new_clustermember->svc_description==NULL){
00230                      if(new_clustermember->host_name!=NULL)
00231                             free(new_clustermember->host_name);
00232                      free(new_clustermember);
00233                      return ERROR;
00234                       }
00235               strcpy(new_clustermember->svc_description,svc);
00236                }
00237 
00238        new_clustermember->next=clustermember_list;
00239        clustermember_list=new_clustermember;
00240 
00241        return OK;
00242         }
00243 
00244 
00245 void free_memory(void){
00246        clustermember *this_clustermember;
00247        clustermember *next_clustermember;
00248 
00249        for(this_clustermember=clustermember_list;this_clustermember!=NULL;this_clustermember=next_clustermember){
00250               next_clustermember=this_clustermember->next;
00251               if(this_clustermember->host_name!=NULL)
00252                      free(this_clustermember->host_name);             
00253               if(this_clustermember->svc_description!=NULL)
00254                      free(this_clustermember->svc_description);
00255               free(this_clustermember);
00256                }
00257 
00258        return;
00259         }
00260 
00261 
00262 
00263 int check_cluster_status(void){
00264        FILE *fp;
00265        clustermember *temp_clustermember;
00266        char input_buffer[MAX_INPUT_BUFFER];
00267        char matching_entry[MAX_INPUT_BUFFER];
00268 
00269        fp=fopen(status_log,"r");
00270        if(fp==NULL){
00271               printf("Error: Could not open status log '%s' for reading\n",status_log);
00272               return ERROR;
00273                }
00274 
00275 #ifdef DEBUG
00276        for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
00277               if(check_type==CHECK_HOSTS)
00278                      printf("Cluster member: '%s'\n",temp_clustermember->host_name);
00279               else
00280                      printf("Cluster member: '%s'/'%s'\n",temp_clustermember->host_name,temp_clustermember->svc_description);
00281                }
00282 #endif
00283 
00284        for(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp);!feof(fp);fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){
00285 
00286               /* this is a host entry */
00287               if(strstr(input_buffer,"] HOST;") && check_type==CHECK_HOSTS){
00288 
00289                      /* this this a match? */
00290                      for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
00291 
00292                             snprintf(matching_entry,sizeof(matching_entry)-1,";%s;",temp_clustermember->host_name);
00293 
00294                             if(strstr(input_buffer,matching_entry)){
00295                                    if(strstr(input_buffer,";DOWN;"))
00296                                           total_hosts_down++;
00297                                    else if(strstr(input_buffer,";UNREACHABLE;"))
00298                                           total_hosts_unreachable++;
00299                                    else if(strstr(input_buffer,";UP;"))
00300                                           total_hosts_up++;
00301                                     }
00302                              }
00303                      
00304                       }
00305 
00306               /* this is a service entry */
00307               else if(strstr(input_buffer,"] SERVICE;") && check_type==CHECK_SERVICES){
00308 
00309                      /* this this a match? */
00310                      for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
00311 
00312                             snprintf(matching_entry,sizeof(matching_entry)-1,";%s;%s;",temp_clustermember->host_name,temp_clustermember->svc_description);
00313 
00314                             if(strstr(input_buffer,matching_entry)){
00315                                    if(strstr(input_buffer,";HOST DOWN;") || strstr(input_buffer,";UNREACHABLE;") || strstr(input_buffer,";CRITICAL;"))
00316                                           total_services_critical++;
00317                                    else if(strstr(input_buffer,";WARNING;"))
00318                                           total_services_warning++;
00319                                    else if(strstr(input_buffer,";UNKNOWN;"))
00320                                           total_services_unknown++;
00321                                    else if(strstr(input_buffer,";OK;") || strstr(input_buffer,";RECOVERY;"))
00322                                           total_services_ok++;
00323                                     }
00324                              }
00325               
00326                       }
00327                }
00328 
00329        fclose(fp);
00330 
00331        return OK;
00332         }