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;"))