1 /*****************************************************************************
3 * CHECK_CLUSTER.C - Host and Service Cluster Plugin for NetSaint
5 * Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org)
7 * Last Modified: 07-08-2000
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *****************************************************************************/
37 #define CHECK_SERVICES 1
40 #define MAX_INPUT_BUFFER 1024
43 #define STATE_WARNING 1
44 #define STATE_CRITICAL 2
45 #define STATE_UNKNOWN 3
47 typedef struct clustermember_struct
{
49 char *svc_description
;
50 struct clustermember_struct
*next
;
54 int check_cluster_status(void);
55 int add_clustermember(char *,char *);
56 void free_memory(void);
58 clustermember
*clustermember_list
=NULL
;
60 int total_services_ok
=0;
61 int total_services_warning
=0;
62 int total_services_unknown
=0;
63 int total_services_critical
=0;
66 int total_hosts_down
=0;
67 int total_hosts_unreachable
=0;
69 char status_log
[MAX_INPUT_BUFFER
]="";
70 int warning_threshold
=0;
71 int critical_threshold
=0;
73 int check_type
=CHECK_SERVICES
;
76 int main(int argc
, char **argv
){
77 char input_buffer
[MAX_INPUT_BUFFER
];
79 char *svc_description
;
80 int return_code
=STATE_OK
;
85 printf("Invalid arguments supplied\n");
88 printf("Host/Service Cluster Plugin for NetSaint\n");
89 printf("Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org)\n");
90 printf("Last Modified: 07-08-2000\n");
91 printf("License: GPL\n");
93 printf("Usage: %s <--service | --host> <status_log> <warn_threshold> <crit_threshold>\n",argv
[0]);
96 printf(" --service = Check service cluster status\n");
97 printf(" --host = Check host cluster status\n");
98 printf(" <status_log> = This is the location of the NetSaint status log\n");
99 printf(" <warn_threshold> = This is the number of hosts or services in\n");
100 printf(" the cluster that must be in a non-OK state\n");
101 printf(" in order to result in a warning status level\n");
102 printf(" <crit_threshold> = This is the number of hosts or services in\n");
103 printf(" the cluster that must be in a non-OK state\n");
104 printf(" in order to result in a critical status level\n");
107 printf("Members of the host or service cluster are read from STDIN.\n");
108 printf("One host or service can be specified per line, services must\n");
109 printf("be in the format of <host_name>;<svc_description>\n");
112 return STATE_UNKNOWN
;
115 /* see if we're checking a host or service clust */
116 if(!strcmp(argv
[1],"--host"))
117 check_type
=CHECK_HOSTS
;
119 check_type
=CHECK_SERVICES
;
121 /* get the status log */
122 strncpy(status_log
,argv
[2],sizeof(status_log
)-1);
123 status_log
[sizeof(status_log
)-1]='\x0';
125 /* get the warning and critical thresholds */
126 warning_threshold
=atoi(argv
[3]);
127 critical_threshold
=atoi(argv
[4]);
130 /* read all data from STDIN until there isn't anymore */
131 while(fgets(input_buffer
,sizeof(input_buffer
)-1,stdin
)){
136 /*strip(input_buffer);*/
138 if(!strcmp(input_buffer
,""))
141 if(!strcmp(input_buffer
,"\n"))
144 /* get the host name */
145 if(check_type
==CHECK_SERVICES
)
146 host_name
=(char *)strtok(input_buffer
,";");
148 host_name
=(char *)strtok(input_buffer
,"\n");
149 if(host_name
==NULL
|| !strcmp(host_name
,"")){
150 printf("Error: Host name is NULL!\n");
154 if(check_type
==CHECK_SERVICES
){
156 /* get the service description */
157 svc_description
=(char *)strtok(NULL
,"\n");
158 if(svc_description
==NULL
|| !strcmp(svc_description
,"")){
159 printf("Error: Service description is NULL!\n");
164 /* add the cluster member to the list in memory */
165 if(add_clustermember(host_name
,svc_description
)!=OK
)
166 printf("Error: Could not add cluster member\n");
169 printf("Added cluster member\n");
174 /* check the status of the cluster */
175 if(check_cluster_status()==OK
){
177 if(check_type
==CHECK_SERVICES
){
178 if((total_services_warning
+total_services_unknown
+total_services_critical
) >= critical_threshold
)
179 return_code
=STATE_CRITICAL
;
180 else if((total_services_warning
+total_services_unknown
+total_services_critical
) >= warning_threshold
)
181 return_code
=STATE_WARNING
;
183 return_code
=STATE_OK
;
185 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
);
188 if((total_hosts_down
+total_hosts_unreachable
) >= critical_threshold
)
189 return_code
=STATE_CRITICAL
;
190 else if((total_hosts_down
+total_hosts_unreachable
) >= warning_threshold
)
191 return_code
=STATE_WARNING
;
193 return_code
=STATE_OK
;
195 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
);
199 return_code
=STATE_UNKNOWN
;
208 int add_clustermember(char *hst
,char *svc
){
209 clustermember
*new_clustermember
;
211 new_clustermember
=(clustermember
*)malloc(sizeof(clustermember
));
212 if(new_clustermember
==NULL
)
215 new_clustermember
->host_name
=NULL
;
216 new_clustermember
->svc_description
=NULL
;
219 new_clustermember
->host_name
=(char *)malloc(strlen(hst
)+1);
220 if(new_clustermember
->host_name
==NULL
){
221 free(new_clustermember
);
224 strcpy(new_clustermember
->host_name
,hst
);
228 new_clustermember
->svc_description
=(char *)malloc(strlen(svc
)+1);
229 if(new_clustermember
->svc_description
==NULL
){
230 if(new_clustermember
->host_name
!=NULL
)
231 free(new_clustermember
->host_name
);
232 free(new_clustermember
);
235 strcpy(new_clustermember
->svc_description
,svc
);
238 new_clustermember
->next
=clustermember_list
;
239 clustermember_list
=new_clustermember
;
245 void free_memory(void){
246 clustermember
*this_clustermember
;
247 clustermember
*next_clustermember
;
249 for(this_clustermember
=clustermember_list
;this_clustermember
!=NULL
;this_clustermember
=next_clustermember
){
250 next_clustermember
=this_clustermember
->next
;
251 if(this_clustermember
->host_name
!=NULL
)
252 free(this_clustermember
->host_name
);
253 if(this_clustermember
->svc_description
!=NULL
)
254 free(this_clustermember
->svc_description
);
255 free(this_clustermember
);
263 int check_cluster_status(void){
265 clustermember
*temp_clustermember
;
266 char input_buffer
[MAX_INPUT_BUFFER
];
267 char matching_entry
[MAX_INPUT_BUFFER
];
269 fp
=fopen(status_log
,"r");
271 printf("Error: Could not open status log '%s' for reading\n",status_log
);
276 for(temp_clustermember
=clustermember_list
;temp_clustermember
!=NULL
;temp_clustermember
=temp_clustermember
->next
){
277 if(check_type
==CHECK_HOSTS
)
278 printf("Cluster member: '%s'\n",temp_clustermember
->host_name
);
280 printf("Cluster member: '%s'/'%s'\n",temp_clustermember
->host_name
,temp_clustermember
->svc_description
);
284 for(fgets(input_buffer
,MAX_INPUT_BUFFER
-1,fp
);!feof(fp
);fgets(input_buffer
,MAX_INPUT_BUFFER
-1,fp
)){
286 /* this is a host entry */
287 if(strstr(input_buffer
,"] HOST;") && check_type
==CHECK_HOSTS
){
289 /* this this a match? */
290 for(temp_clustermember
=clustermember_list
;temp_clustermember
!=NULL
;temp_clustermember
=temp_clustermember
->next
){
292 snprintf(matching_entry
,sizeof(matching_entry
)-1,";%s;",temp_clustermember
->host_name
);
294 if(strstr(input_buffer
,matching_entry
)){
295 if(strstr(input_buffer
,";DOWN;"))
297 else if(strstr(input_buffer
,";UNREACHABLE;"))
298 total_hosts_unreachable
++;
299 else if(strstr(input_buffer
,";UP;"))
306 /* this is a service entry */
307 else if(strstr(input_buffer
,"] SERVICE;") && check_type
==CHECK_SERVICES
){
309 /* this this a match? */
310 for(temp_clustermember
=clustermember_list
;temp_clustermember
!=NULL
;temp_clustermember
=temp_clustermember
->next
){
312 snprintf(matching_entry
,sizeof(matching_entry
)-1,";%s;%s;",temp_clustermember
->host_name
,temp_clustermember
->svc_description
);
314 if(strstr(input_buffer
,matching_entry
)){
315 if(strstr(input_buffer
,";HOST DOWN;") || strstr(input_buffer
,";UNREACHABLE;") || strstr(input_buffer
,";CRITICAL;"))
316 total_services_critical
++;
317 else if(strstr(input_buffer
,";WARNING;"))
318 total_services_warning
++;
319 else if(strstr(input_buffer
,";UNKNOWN;"))
320 total_services_unknown
++;
321 else if(strstr(input_buffer
,";OK;") || strstr(input_buffer
,";RECOVERY;"))