4
0

check_load.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /******************************************************************************
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  13. ******************************************************************************/
  14. const char *progname = "check_load";
  15. const char *revision = "$Revision$";
  16. const char *copyright = "1999-2003";
  17. const char *email = "nagiosplug-devel@lists.sourceforge.net";
  18. #include "common.h"
  19. #include "utils.h"
  20. #include "popen.h"
  21. #ifdef HAVE_SYS_LOADAVG_H
  22. #include <sys/loadavg.h>
  23. #endif
  24. /* needed for compilation under NetBSD, as suggested by Andy Doran */
  25. #ifndef LOADAVG_1MIN
  26. #define LOADAVG_1MIN 0
  27. #define LOADAVG_5MIN 1
  28. #define LOADAVG_15MIN 2
  29. #endif /* !defined LOADAVG_1MIN */
  30. int process_arguments (int argc, char **argv);
  31. int validate_arguments (void);
  32. void print_help (void);
  33. void print_usage (void);
  34. float wload1 = -1, wload5 = -1, wload15 = -1;
  35. float cload1 = -1, cload5 = -1, cload15 = -1;
  36. char *status_line;
  37. int
  38. main (int argc, char **argv)
  39. {
  40. #if HAVE_GETLOADAVG==1
  41. int result;
  42. double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about unitialized arrays */
  43. #else
  44. # if HAVE_PROC_LOADAVG==1
  45. FILE *fp;
  46. char input_buffer[MAX_INPUT_BUFFER];
  47. char *tmp_ptr;
  48. # else
  49. int result;
  50. char input_buffer[MAX_INPUT_BUFFER];
  51. # endif
  52. #endif
  53. float la1, la5, la15;
  54. if (process_arguments (argc, argv) == ERROR)
  55. usage ("failed processing arguments\n");
  56. #if HAVE_GETLOADAVG==1
  57. result = getloadavg (la, 3);
  58. if (result == -1)
  59. return STATE_UNKNOWN;
  60. la1 = la[LOADAVG_1MIN];
  61. la5 = la[LOADAVG_5MIN];
  62. la15 = la[LOADAVG_15MIN];
  63. #else
  64. # if HAVE_PROC_LOADAVG==1
  65. fp = fopen (PROC_LOADAVG, "r");
  66. if (fp == NULL) {
  67. printf (_("Error opening %s\n"), PROC_LOADAVG);
  68. return STATE_UNKNOWN;
  69. }
  70. la1 = la5 = la15 = -1;
  71. while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
  72. tmp_ptr = strtok (input_buffer, " ");
  73. la1 = atof (tmp_ptr);
  74. tmp_ptr = strtok (NULL, " ");
  75. la5 = atof (tmp_ptr);
  76. tmp_ptr = strtok (NULL, " ");
  77. la15 = atof (tmp_ptr);
  78. }
  79. fclose (fp);
  80. # else
  81. child_process = spopen (PATH_TO_UPTIME);
  82. if (child_process == NULL) {
  83. printf (_("Error opening %s\n"), PATH_TO_UPTIME);
  84. return STATE_UNKNOWN;
  85. }
  86. child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
  87. if (child_stderr == NULL) {
  88. printf (_("Could not open stderr for %s\n"), PATH_TO_UPTIME);
  89. }
  90. fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
  91. sscanf (input_buffer, "%*[^l]load average: %f, %f, %f"), &la1, &la5, &la15);
  92. result = spclose (child_process);
  93. if (result) {
  94. printf (_("Error code %d returned in %s\n"), result, PATH_TO_UPTIME);
  95. return STATE_UNKNOWN;
  96. }
  97. # endif
  98. #endif
  99. if ((la1 < 0.0) || (la5 < 0.0) || (la15 < 0.0)) {
  100. #if HAVE_GETLOADAVG==1
  101. printf (_("Error in getloadavg()\n"));
  102. #else
  103. # if HAVE_PROC_LOADAVG==1
  104. printf (_("Error processing %s\n"), PROC_LOADAVG);
  105. # else
  106. printf (_("Error processing %s\n"), PATH_TO_UPTIME);
  107. # endif
  108. #endif
  109. return STATE_UNKNOWN;
  110. }
  111. asprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15);
  112. if ((la1 >= cload1) || (la5 >= cload5) || (la15 >= cload15)) {
  113. printf(_("CRITICAL - %s\n"), status_line);
  114. return STATE_CRITICAL;
  115. }
  116. if ((la1 >= wload1) || (la5 >= wload5) || (la15 >= wload15)) {
  117. printf (_("WARNING - %s\n"), status_line);
  118. return STATE_WARNING;
  119. }
  120. printf (_("OK - %s\n"), status_line);
  121. return STATE_OK;
  122. }
  123. /* process command-line arguments */
  124. int
  125. process_arguments (int argc, char **argv)
  126. {
  127. int c = 0;
  128. int option = 0;
  129. static struct option longopts[] = {
  130. {"warning", required_argument, 0, 'w'},
  131. {"critical", required_argument, 0, 'c'},
  132. {"version", no_argument, 0, 'V'},
  133. {"help", no_argument, 0, 'h'},
  134. {0, 0, 0, 0}
  135. };
  136. if (argc < 2)
  137. return ERROR;
  138. while (1) {
  139. c = getopt_long (argc, argv, "Vhc:w:", longopts, &option);
  140. if (c == -1 || c == EOF)
  141. break;
  142. switch (c) {
  143. case 'w': /* warning time threshold */
  144. if (is_intnonneg (optarg)) {
  145. wload1 = atof (optarg);
  146. wload5 = atof (optarg);
  147. wload15 = atof (optarg);
  148. break;
  149. }
  150. else if (strstr (optarg, ",") &&
  151. sscanf (optarg, "%f,%f,%f", &wload1, &wload5, &wload15) == 3)
  152. break;
  153. else if (strstr (optarg, ":") &&
  154. sscanf (optarg, "%f:%f:%f", &wload1, &wload5, &wload15) == 3)
  155. break;
  156. else
  157. usage (_("Warning threshold must be float or float triplet!\n"));
  158. break;
  159. case 'c': /* critical time threshold */
  160. if (is_intnonneg (optarg)) {
  161. cload1 = atof (optarg);
  162. cload5 = atof (optarg);
  163. cload15 = atof (optarg);
  164. break;
  165. }
  166. else if (strstr (optarg, ",") &&
  167. sscanf (optarg, "%f,%f,%f", &cload1, &cload5, &cload15) == 3)
  168. break;
  169. else if (strstr (optarg, ":") &&
  170. sscanf (optarg, "%f:%f:%f", &cload1, &cload5, &cload15) == 3)
  171. break;
  172. else
  173. usage (_("Critical threshold must be float or float triplet!\n"));
  174. break;
  175. case 'V': /* version */
  176. print_revision (progname, "$Revision$");
  177. exit (STATE_OK);
  178. case 'h': /* help */
  179. print_help ();
  180. exit (STATE_OK);
  181. case '?': /* help */
  182. usage (_("Invalid argument\n"));
  183. }
  184. }
  185. c = optind;
  186. if (c == argc)
  187. return validate_arguments ();
  188. if (wload1 < 0 && is_nonnegative (argv[c]))
  189. wload1 = atof (argv[c++]);
  190. if (c == argc)
  191. return validate_arguments ();
  192. if (cload1 < 0 && is_nonnegative (argv[c]))
  193. cload1 = atof (argv[c++]);
  194. if (c == argc)
  195. return validate_arguments ();
  196. if (wload5 < 0 && is_nonnegative (argv[c]))
  197. wload5 = atof (argv[c++]);
  198. if (c == argc)
  199. return validate_arguments ();
  200. if (cload5 < 0 && is_nonnegative (argv[c]))
  201. cload5 = atof (argv[c++]);
  202. if (c == argc)
  203. return validate_arguments ();
  204. if (wload15 < 0 && is_nonnegative (argv[c]))
  205. wload15 = atof (argv[c++]);
  206. if (c == argc)
  207. return validate_arguments ();
  208. if (cload15 < 0 && is_nonnegative (argv[c]))
  209. cload15 = atof (argv[c++]);
  210. return validate_arguments ();
  211. }
  212. int
  213. validate_arguments (void)
  214. {
  215. if (wload1 < 0)
  216. usage (_("Warning threshold for 1-minute load average is not specified\n"));
  217. if (wload5 < 0)
  218. usage (_("Warning threshold for 5-minute load average is not specified\n"));
  219. if (wload15 < 0)
  220. usage (_("Warning threshold for 15-minute load average is not specified\n"));
  221. if (cload1 < 0)
  222. usage (_("Critical threshold for 1-minute load average is not specified\n"));
  223. if (cload5 < 0)
  224. usage (_("Critical threshold for 5-minute load average is not specified\n"));
  225. if (cload15 < 0)
  226. usage (_("Critical threshold for 15-minute load average is not specified\n"));
  227. if (wload1 > cload1)
  228. usage (_("Parameter inconsistency: 1-minute \"warning load\" greater than \"critical load\".\n"));
  229. if (wload5 > cload5)
  230. usage (_("Parameter inconsistency: 5-minute \"warning load\" greater than \"critical load\".\n"));
  231. if (wload15 > cload15)
  232. usage (_("Parameter inconsistency: 15-minute \"warning load\" greater than \"critical load\".\n"));
  233. return OK;
  234. }
  235. void
  236. print_help (void)
  237. {
  238. print_revision (progname, revision);
  239. printf (_("Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>\n"));
  240. printf (_(COPYRIGHT), copyright, email);
  241. printf (_("This plugin tests the current system load average.\n\n"));
  242. print_usage ();
  243. printf (_(UT_HELP_VRSN));
  244. printf (_("\
  245. -w, --warning=WLOAD1,WLOAD5,WLOAD15\n\
  246. Exit with WARNING status if load average exceeds WLOADn\n\
  247. -c, --critical=CLOAD1,CLOAD5,CLOAD15\n\
  248. Exit with CRITICAL status if load average exceed CLOADn\n\n\
  249. the load average format is the same used by \"uptime\" and \"w\"\n\n"));
  250. printf (_(UT_SUPPORT));
  251. }
  252. void
  253. print_usage (void)
  254. {
  255. printf (_("Usage: %s -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n"),
  256. progname);
  257. printf (_(UT_HLP_VRS), progname, progname);
  258. }