check_cluster.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. #include <stdio.h>
  27. #include <stdlib.h>
  28. #define OK 0
  29. #define ERROR -1
  30. #define TRUE 1
  31. #define FALSE 0
  32. #define CHECK_SERVICES 1
  33. #define CHECK_HOSTS 2
  34. #define MAX_INPUT_BUFFER 1024
  35. #define STATE_OK 0
  36. #define STATE_WARNING 1
  37. #define STATE_CRITICAL 2
  38. #define STATE_UNKNOWN 3
  39. typedef struct clustermember_struct{
  40. char *host_name;
  41. char *svc_description;
  42. struct clustermember_struct *next;
  43. }clustermember;
  44. int check_cluster_status(void);
  45. int add_clustermember(char *,char *);
  46. void free_memory(void);
  47. clustermember *clustermember_list=NULL;
  48. int total_services_ok=0;
  49. int total_services_warning=0;
  50. int total_services_unknown=0;
  51. int total_services_critical=0;
  52. int total_hosts_up=0;
  53. int total_hosts_down=0;
  54. int total_hosts_unreachable=0;
  55. char status_log[MAX_INPUT_BUFFER]="";
  56. int warning_threshold=0;
  57. int critical_threshold=0;
  58. int check_type=CHECK_SERVICES;
  59. int main(int argc, char **argv){
  60. char input_buffer[MAX_INPUT_BUFFER];
  61. char *host_name;
  62. char *svc_description;
  63. int return_code=STATE_OK;
  64. int error=FALSE;
  65. if(argc!=5){
  66. printf("Invalid arguments supplied\n");
  67. printf("\n");
  68. printf("Host/Service Cluster Plugin for NetSaint\n");
  69. printf("Copyright (c) 2000 Ethan Galstad (netsaint@netsaint.org)\n");
  70. printf("Last Modified: 07-08-2000\n");
  71. printf("License: GPL\n");
  72. printf("\n");
  73. printf("Usage: %s <--service | --host> <status_log> <warn_threshold> <crit_threshold>\n",argv[0]);
  74. printf("\n");
  75. printf("Options:\n");
  76. printf(" --service = Check service cluster status\n");
  77. printf(" --host = Check host cluster status\n");
  78. printf(" <status_log> = This is the location of the NetSaint status log\n");
  79. printf(" <warn_threshold> = This is the number of hosts or services in\n");
  80. printf(" the cluster that must be in a non-OK state\n");
  81. printf(" in order to result in a warning status level\n");
  82. printf(" <crit_threshold> = This is the number of hosts or services in\n");
  83. printf(" the cluster that must be in a non-OK state\n");
  84. printf(" in order to result in a critical status level\n");
  85. printf("\n");
  86. printf("Notes:\n");
  87. printf("Members of the host or service cluster are read from STDIN.\n");
  88. printf("One host or service can be specified per line, services must\n");
  89. printf("be in the format of <host_name>;<svc_description>\n");
  90. printf("\n");
  91. return STATE_UNKNOWN;
  92. }
  93. /* see if we're checking a host or service clust */
  94. if(!strcmp(argv[1],"--host"))
  95. check_type=CHECK_HOSTS;
  96. else
  97. check_type=CHECK_SERVICES;
  98. /* get the status log */
  99. strncpy(status_log,argv[2],sizeof(status_log)-1);
  100. status_log[sizeof(status_log)-1]='\x0';
  101. /* get the warning and critical thresholds */
  102. warning_threshold=atoi(argv[3]);
  103. critical_threshold=atoi(argv[4]);
  104. /* read all data from STDIN until there isn't anymore */
  105. while(fgets(input_buffer,sizeof(input_buffer)-1,stdin)){
  106. if(feof(stdin))
  107. break;
  108. /*strip(input_buffer);*/
  109. if(!strcmp(input_buffer,""))
  110. continue;
  111. if(!strcmp(input_buffer,"\n"))
  112. continue;
  113. /* get the host name */
  114. if(check_type==CHECK_SERVICES)
  115. host_name=(char *)strtok(input_buffer,";");
  116. else
  117. host_name=(char *)strtok(input_buffer,"\n");
  118. if(host_name==NULL || !strcmp(host_name,"")){
  119. printf("Error: Host name is NULL!\n");
  120. continue;
  121. }
  122. if(check_type==CHECK_SERVICES){
  123. /* get the service description */
  124. svc_description=(char *)strtok(NULL,"\n");
  125. if(svc_description==NULL || !strcmp(svc_description,"")){
  126. printf("Error: Service description is NULL!\n");
  127. continue;
  128. }
  129. }
  130. /* add the cluster member to the list in memory */
  131. if(add_clustermember(host_name,svc_description)!=OK)
  132. printf("Error: Could not add cluster member\n");
  133. #ifdef DEBUG
  134. else
  135. printf("Added cluster member\n");
  136. #endif
  137. }
  138. /* check the status of the cluster */
  139. if(check_cluster_status()==OK){
  140. if(check_type==CHECK_SERVICES){
  141. if((total_services_warning+total_services_unknown+total_services_critical) >= critical_threshold)
  142. return_code=STATE_CRITICAL;
  143. else if((total_services_warning+total_services_unknown+total_services_critical) >= warning_threshold)
  144. return_code=STATE_WARNING;
  145. else
  146. return_code=STATE_OK;
  147. 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);
  148. }
  149. else{
  150. if((total_hosts_down+total_hosts_unreachable) >= critical_threshold)
  151. return_code=STATE_CRITICAL;
  152. else if((total_hosts_down+total_hosts_unreachable) >= warning_threshold)
  153. return_code=STATE_WARNING;
  154. else
  155. return_code=STATE_OK;
  156. 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);
  157. }
  158. }
  159. else
  160. return_code=STATE_UNKNOWN;
  161. free_memory();
  162. return return_code;
  163. }
  164. int add_clustermember(char *hst,char *svc){
  165. clustermember *new_clustermember;
  166. new_clustermember=(clustermember *)malloc(sizeof(clustermember));
  167. if(new_clustermember==NULL)
  168. return ERROR;
  169. new_clustermember->host_name=NULL;
  170. new_clustermember->svc_description=NULL;
  171. if(hst!=NULL){
  172. new_clustermember->host_name=(char *)malloc(strlen(hst)+1);
  173. if(new_clustermember->host_name==NULL){
  174. free(new_clustermember);
  175. return ERROR;
  176. }
  177. strcpy(new_clustermember->host_name,hst);
  178. }
  179. if(svc!=NULL){
  180. new_clustermember->svc_description=(char *)malloc(strlen(svc)+1);
  181. if(new_clustermember->svc_description==NULL){
  182. if(new_clustermember->host_name!=NULL)
  183. free(new_clustermember->host_name);
  184. free(new_clustermember);
  185. return ERROR;
  186. }
  187. strcpy(new_clustermember->svc_description,svc);
  188. }
  189. new_clustermember->next=clustermember_list;
  190. clustermember_list=new_clustermember;
  191. return OK;
  192. }
  193. void free_memory(void){
  194. clustermember *this_clustermember;
  195. clustermember *next_clustermember;
  196. for(this_clustermember=clustermember_list;this_clustermember!=NULL;this_clustermember=next_clustermember){
  197. next_clustermember=this_clustermember->next;
  198. if(this_clustermember->host_name!=NULL)
  199. free(this_clustermember->host_name);
  200. if(this_clustermember->svc_description!=NULL)
  201. free(this_clustermember->svc_description);
  202. free(this_clustermember);
  203. }
  204. return;
  205. }
  206. int check_cluster_status(void){
  207. FILE *fp;
  208. clustermember *temp_clustermember;
  209. char input_buffer[MAX_INPUT_BUFFER];
  210. char matching_entry[MAX_INPUT_BUFFER];
  211. fp=fopen(status_log,"r");
  212. if(fp==NULL){
  213. printf("Error: Could not open status log '%s' for reading\n",status_log);
  214. return ERROR;
  215. }
  216. #ifdef DEBUG
  217. for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
  218. if(check_type==CHECK_HOSTS)
  219. printf("Cluster member: '%s'\n",temp_clustermember->host_name);
  220. else
  221. printf("Cluster member: '%s'/'%s'\n",temp_clustermember->host_name,temp_clustermember->svc_description);
  222. }
  223. #endif
  224. for(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp);!feof(fp);fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){
  225. /* this is a host entry */
  226. if(strstr(input_buffer,"] HOST;") && check_type==CHECK_HOSTS){
  227. /* this this a match? */
  228. for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
  229. snprintf(matching_entry,sizeof(matching_entry)-1,";%s;",temp_clustermember->host_name);
  230. if(strstr(input_buffer,matching_entry)){
  231. if(strstr(input_buffer,";DOWN;"))
  232. total_hosts_down++;
  233. else if(strstr(input_buffer,";UNREACHABLE;"))
  234. total_hosts_unreachable++;
  235. else if(strstr(input_buffer,";UP;"))
  236. total_hosts_up++;
  237. }
  238. }
  239. }
  240. /* this is a service entry */
  241. else if(strstr(input_buffer,"] SERVICE;") && check_type==CHECK_SERVICES){
  242. /* this this a match? */
  243. for(temp_clustermember=clustermember_list;temp_clustermember!=NULL;temp_clustermember=temp_clustermember->next){
  244. snprintf(matching_entry,sizeof(matching_entry)-1,";%s;%s;",temp_clustermember->host_name,temp_clustermember->svc_description);
  245. if(strstr(input_buffer,matching_entry)){
  246. if(strstr(input_buffer,";HOST DOWN;") || strstr(input_buffer,";UNREACHABLE;") || strstr(input_buffer,";CRITICAL;"))
  247. total_services_critical++;
  248. else if(strstr(input_buffer,";WARNING;"))
  249. total_services_warning++;
  250. else if(strstr(input_buffer,";UNKNOWN;"))
  251. total_services_unknown++;
  252. else if(strstr(input_buffer,";OK;") || strstr(input_buffer,";RECOVERY;"))
  253. total_services_ok++;
  254. }
  255. }
  256. }
  257. }
  258. fclose(fp);
  259. return OK;
  260. }