diff options
-rw-r--r-- | contrib/check_cluster.c | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/contrib/check_cluster.c b/contrib/check_cluster.c new file mode 100644 index 0000000..06519e6 --- /dev/null +++ b/contrib/check_cluster.c | |||
@@ -0,0 +1,332 @@ | |||
1 | /***************************************************************************** | ||
2 | * | ||
3 | * CHECK_CLUSTER.C - Host and Service Cluster Plugin for NetSaint | ||
4 | * | ||
5 | * Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org) | ||
6 | * License: GPL | ||
7 | * Last Modified: 07-08-2000 | ||
8 | * | ||
9 | * License: | ||
10 | * | ||
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. | ||
15 | * | ||
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. | ||
20 | * | ||
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. | ||
24 | * | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | |||
28 | #include <stdio.h> | ||
29 | #include <stdlib.h> | ||
30 | |||
31 | #define OK 0 | ||
32 | #define ERROR -1 | ||
33 | |||
34 | #define TRUE 1 | ||
35 | #define FALSE 0 | ||
36 | |||
37 | #define CHECK_SERVICES 1 | ||
38 | #define CHECK_HOSTS 2 | ||
39 | |||
40 | #define MAX_INPUT_BUFFER 1024 | ||
41 | |||
42 | #define STATE_OK 0 | ||
43 | #define STATE_WARNING 1 | ||
44 | #define STATE_CRITICAL 2 | ||
45 | #define STATE_UNKNOWN 3 | ||
46 | |||
47 | typedef struct clustermember_struct{ | ||
48 | char *host_name; | ||
49 | char *svc_description; | ||
50 | struct clustermember_struct *next; | ||
51 | }clustermember; | ||
52 | |||
53 | |||
54 | int check_cluster_status(void); | ||
55 | int add_clustermember(char *,char *); | ||
56 | void free_memory(void); | ||
57 | |||
58 | clustermember *clustermember_list=NULL; | ||
59 | |||
60 | int total_services_ok=0; | ||
61 | int total_services_warning=0; | ||
62 | int total_services_unknown=0; | ||
63 | int total_services_critical=0; | ||
64 | |||
65 | int total_hosts_up=0; | ||
66 | int total_hosts_down=0; | ||
67 | int total_hosts_unreachable=0; | ||
68 | |||
69 | char status_log[MAX_INPUT_BUFFER]=""; | ||
70 | int warning_threshold=0; | ||
71 | int critical_threshold=0; | ||
72 | |||
73 | int check_type=CHECK_SERVICES; | ||
74 | |||
75 | |||
76 | int main(int argc, char **argv){ | ||
77 | char input_buffer[MAX_INPUT_BUFFER]; | ||
78 | char *host_name; | ||
79 | char *svc_description; | ||
80 | int return_code=STATE_OK; | ||
81 | int error=FALSE; | ||
82 | |||
83 | if(argc!=5){ | ||
84 | |||
85 | printf("Invalid arguments supplied\n"); | ||
86 | printf("\n"); | ||
87 | |||
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"); | ||
92 | printf("\n"); | ||
93 | printf("Usage: %s <--service | --host> <status_log> <warn_threshold> <crit_threshold>\n",argv[0]); | ||
94 | printf("\n"); | ||
95 | printf("Options:\n"); | ||
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"); | ||
105 | printf("\n"); | ||
106 | printf("Notes:\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"); | ||
110 | printf("\n"); | ||
111 | |||
112 | return STATE_UNKNOWN; | ||
113 | } | ||
114 | |||
115 | /* see if we're checking a host or service clust */ | ||
116 | if(!strcmp(argv[1],"--host")) | ||
117 | check_type=CHECK_HOSTS; | ||
118 | else | ||
119 | check_type=CHECK_SERVICES; | ||
120 | |||
121 | /* get the status log */ | ||
122 | strncpy(status_log,argv[2],sizeof(status_log)-1); | ||
123 | status_log[sizeof(status_log)-1]='\x0'; | ||
124 | |||
125 | /* get the warning and critical thresholds */ | ||
126 | warning_threshold=atoi(argv[3]); | ||
127 | critical_threshold=atoi(argv[4]); | ||
128 | |||
129 | |||
130 | /* read all data from STDIN until there isn't anymore */ | ||
131 | while(fgets(input_buffer,sizeof(input_buffer)-1,stdin)){ | ||
132 | |||
133 | if(feof(stdin)) | ||
134 | break; | ||
135 | |||
136 | /*strip(input_buffer);*/ | ||
137 | |||
138 | if(!strcmp(input_buffer,"")) | ||
139 | continue; | ||
140 | |||
141 | if(!strcmp(input_buffer,"\n")) | ||
142 | continue; | ||
143 | |||
144 | /* get the host name */ | ||
145 | if(check_type==CHECK_SERVICES) | ||
146 | host_name=(char *)strtok(input_buffer,";"); | ||
147 | else | ||
148 | host_name=(char *)strtok(input_buffer,"\n"); | ||
149 | if(host_name==NULL || !strcmp(host_name,"")){ | ||
150 | printf("Error: Host name is NULL!\n"); | ||
151 | continue; | ||
152 | } | ||
153 | |||
154 | if(check_type==CHECK_SERVICES){ | ||
155 | |||
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"); | ||
160 | continue; | ||
161 | } | ||
162 | } | ||
163 | |||
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"); | ||
167 | #ifdef DEBUG | ||
168 | else | ||
169 | printf("Added cluster member\n"); | ||
170 | #endif | ||
171 | } | ||
172 | |||
173 | |||
174 | /* check the status of the cluster */ | ||
175 | if(check_cluster_status()==OK){ | ||
176 | |||
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; | ||
182 | else | ||
183 | return_code=STATE_OK; | ||
184 | |||
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); | ||
186 | } | ||
187 | else{ | ||
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; | ||
192 | else | ||
193 | return_code=STATE_OK; | ||
194 | |||
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); | ||
196 | } | ||
197 | } | ||
198 | else | ||
199 | return_code=STATE_UNKNOWN; | ||
200 | |||
201 | free_memory(); | ||
202 | |||
203 | return return_code; | ||
204 | } | ||
205 | |||
206 | |||
207 | |||
208 | int add_clustermember(char *hst,char *svc){ | ||
209 | clustermember *new_clustermember; | ||
210 | |||
211 | new_clustermember=(clustermember *)malloc(sizeof(clustermember)); | ||
212 | if(new_clustermember==NULL) | ||
213 | return ERROR; | ||
214 | |||
215 | new_clustermember->host_name=NULL; | ||
216 | new_clustermember->svc_description=NULL; | ||
217 | |||
218 | if(hst!=NULL){ | ||
219 | new_clustermember->host_name=(char *)malloc(strlen(hst)+1); | ||
220 | if(new_clustermember->host_name==NULL){ | ||
221 | free(new_clustermember); | ||
222 | return ERROR; | ||
223 | } | ||
224 | strcpy(new_clustermember->host_name,hst); | ||
225 | } | ||
226 | |||
227 | if(svc!=NULL){ | ||
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); | ||
233 | return ERROR; | ||
234 | } | ||
235 | strcpy(new_clustermember->svc_description,svc); | ||
236 | } | ||
237 | |||
238 | new_clustermember->next=clustermember_list; | ||
239 | clustermember_list=new_clustermember; | ||
240 | |||
241 | return OK; | ||
242 | } | ||
243 | |||
244 | |||
245 | void free_memory(void){ | ||
246 | clustermember *this_clustermember; | ||
247 | clustermember *next_clustermember; | ||
248 | |||
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); | ||
256 | } | ||
257 | |||
258 | return; | ||
259 | } | ||
260 | |||
261 | |||
262 | |||
263 | int check_cluster_status(void){ | ||
264 | FILE *fp; | ||
265 | clustermember *temp_clustermember; | ||
266 | char input_buffer[MAX_INPUT_BUFFER]; | ||
267 | char matching_entry[MAX_INPUT_BUFFER]; | ||
268 | |||
269 | fp=fopen(status_log,"r"); | ||
270 | if(fp==NULL){ | ||
271 | printf("Error: Could not open status log '%s' for reading\n",status_log); | ||
272 | return ERROR; | ||
273 | } | ||
274 | |||
275 | #ifdef DEBUG | ||
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); | ||
279 | else | ||
280 | printf("Cluster member: '%s'/'%s'\n",temp_clustermember->host_name,temp_clustermember->svc_description); | ||
281 | } | ||
282 | #endif | ||
283 | |||
284 | for(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp);!feof(fp);fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){ | ||
285 | |||
286 | /* this is a host entry */ | ||
287 | if(strstr(input_buffer,"] HOST;") && check_type==CHECK_HOSTS){ | ||
288 | |||
289 | /* this this a match? */ | ||
290 | for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){ | ||
291 | |||
292 | snprintf(matching_entry,sizeof(matching_entry)-1,";%s;",temp_clustermember->host_name); | ||
293 | |||
294 | if(strstr(input_buffer,matching_entry)){ | ||
295 | if(strstr(input_buffer,";DOWN;")) | ||
296 | total_hosts_down++; | ||
297 | else if(strstr(input_buffer,";UNREACHABLE;")) | ||
298 | total_hosts_unreachable++; | ||
299 | else if(strstr(input_buffer,";UP;")) | ||
300 | total_hosts_up++; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | } | ||
305 | |||
306 | /* this is a service entry */ | ||
307 | else if(strstr(input_buffer,"] SERVICE;") && check_type==CHECK_SERVICES){ | ||
308 | |||
309 | /* this this a match? */ | ||
310 | for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){ | ||
311 | |||
312 | snprintf(matching_entry,sizeof(matching_entry)-1,";%s;%s;",temp_clustermember->host_name,temp_clustermember->svc_description); | ||
313 | |||
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;")) | ||
322 | total_services_ok++; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | } | ||
327 | } | ||
328 | |||
329 | fclose(fp); | ||
330 | |||
331 | return OK; | ||
332 | } | ||