check_load.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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. setlocale (LC_ALL, "");
  55. bindtextdomain (PACKAGE, LOCALEDIR);
  56. textdomain (PACKAGE);
  57. if (process_arguments (argc, argv) == ERROR)
  58. usage ("failed processing arguments\n");
  59. #if HAVE_GETLOADAVG==1
  60. result = getloadavg (la, 3);
  61. if (result == -1)
  62. return STATE_UNKNOWN;
  63. la1 = la[LOADAVG_1MIN];
  64. la5 = la[LOADAVG_5MIN];
  65. la15 = la[LOADAVG_15MIN];
  66. #else
  67. # if HAVE_PROC_LOADAVG==1
  68. fp = fopen (PROC_LOADAVG, "r");
  69. if (fp == NULL) {
  70. printf (_("Error opening %s\n"), PROC_LOADAVG);
  71. return STATE_UNKNOWN;
  72. }
  73. la1 = la5 = la15 = -1;
  74. while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
  75. tmp_ptr = strtok (input_buffer, " ");
  76. la1 = atof (tmp_ptr);
  77. tmp_ptr = strtok (NULL, " ");
  78. la5 = atof (tmp_ptr);
  79. tmp_ptr = strtok (NULL, " ");
  80. la15 = atof (tmp_ptr);
  81. }
  82. fclose (fp);
  83. # else
  84. child_process = spopen (PATH_TO_UPTIME);
  85. if (child_process == NULL) {
  86. printf (_("Error opening %s\n"), PATH_TO_UPTIME);
  87. return STATE_UNKNOWN;
  88. }
  89. child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
  90. if (child_stderr == NULL) {
  91. printf (_("Could not open stderr for %s\n"), PATH_TO_UPTIME);
  92. }
  93. fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
  94. sscanf (input_buffer, "%*[^l]load average: %f, %f, %f"), &la1, &la5, &la15);
  95. result = spclose (child_process);
  96. if (result) {
  97. printf (_("Error code %d returned in %s\n"), result, PATH_TO_UPTIME);
  98. return STATE_UNKNOWN;
  99. }
  100. # endif
  101. #endif
  102. if ((la1 < 0.0) || (la5 < 0.0) || (la15 < 0.0)) {
  103. #if HAVE_GETLOADAVG==1
  104. printf (_("Error in getloadavg()\n"));
  105. #else
  106. # if HAVE_PROC_LOADAVG==1
  107. printf (_("Error processing %s\n"), PROC_LOADAVG);
  108. # else
  109. printf (_("Error processing %s\n"), PATH_TO_UPTIME);
  110. # endif
  111. #endif
  112. return STATE_UNKNOWN;
  113. }
  114. asprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15);
  115. if ((la1 >= cload1) || (la5 >= cload5) || (la15 >= cload15)) {
  116. printf(_("CRITICAL - %s\n"), status_line);
  117. return STATE_CRITICAL;
  118. }
  119. if ((la1 >= wload1) || (la5 >= wload5) || (la15 >= wload15)) {
  120. printf (_("WARNING - %s\n"), status_line);
  121. return STATE_WARNING;
  122. }
  123. printf (_("OK - %s\n"), status_line);
  124. return STATE_OK;
  125. }
  126. /* process command-line arguments */
  127. int
  128. process_arguments (int argc, char **argv)
  129. {
  130. int c = 0;
  131. int option = 0;
  132. static struct option longopts[] = {
  133. {"warning", required_argument, 0, 'w'},
  134. {"critical", required_argument, 0, 'c'},
  135. {"version", no_argument, 0, 'V'},
  136. {"help", no_argument, 0, 'h'},
  137. {0, 0, 0, 0}
  138. };
  139. if (argc < 2)
  140. return ERROR;
  141. while (1) {
  142. c = getopt_long (argc, argv, "Vhc:w:", longopts, &option);
  143. if (c == -1 || c == EOF)
  144. break;
  145. switch (c) {
  146. case 'w': /* warning time threshold */
  147. if (is_intnonneg (optarg)) {
  148. wload1 = atof (optarg);
  149. wload5 = atof (optarg);
  150. wload15 = atof (optarg);
  151. break;
  152. }
  153. else if (strstr (optarg, ",") &&
  154. sscanf (optarg, "%f,%f,%f", &wload1, &wload5, &wload15) == 3)
  155. break;
  156. else if (strstr (optarg, ":") &&
  157. sscanf (optarg, "%f:%f:%f", &wload1, &wload5, &wload15) == 3)
  158. break;
  159. else
  160. usage (_("Warning threshold must be float or float triplet!\n"));
  161. break;
  162. case 'c': /* critical time threshold */
  163. if (is_intnonneg (optarg)) {
  164. cload1 = atof (optarg);
  165. cload5 = atof (optarg);
  166. cload15 = atof (optarg);
  167. break;
  168. }
  169. else if (strstr (optarg, ",") &&
  170. sscanf (optarg, "%f,%f,%f", &cload1, &cload5, &cload15) == 3)
  171. break;
  172. else if (strstr (optarg, ":") &&
  173. sscanf (optarg, "%f:%f:%f", &cload1, &cload5, &cload15) == 3)
  174. break;
  175. else
  176. usage (_("Critical threshold must be float or float triplet!\n"));
  177. break;
  178. case 'V': /* version */
  179. print_revision (progname, "$Revision$");
  180. exit (STATE_OK);
  181. case 'h': /* help */
  182. print_help ();
  183. exit (STATE_OK);
  184. case '?': /* help */
  185. usage (_("Invalid argument\n"));
  186. }
  187. }
  188. c = optind;
  189. if (c == argc)
  190. return validate_arguments ();
  191. if (wload1 < 0 && is_nonnegative (argv[c]))
  192. wload1 = atof (argv[c++]);
  193. if (c == argc)
  194. return validate_arguments ();
  195. if (cload1 < 0 && is_nonnegative (argv[c]))
  196. cload1 = atof (argv[c++]);
  197. if (c == argc)
  198. return validate_arguments ();
  199. if (wload5 < 0 && is_nonnegative (argv[c]))
  200. wload5 = atof (argv[c++]);
  201. if (c == argc)
  202. return validate_arguments ();
  203. if (cload5 < 0 && is_nonnegative (argv[c]))
  204. cload5 = atof (argv[c++]);
  205. if (c == argc)
  206. return validate_arguments ();
  207. if (wload15 < 0 && is_nonnegative (argv[c]))
  208. wload15 = atof (argv[c++]);
  209. if (c == argc)
  210. return validate_arguments ();
  211. if (cload15 < 0 && is_nonnegative (argv[c]))
  212. cload15 = atof (argv[c++]);
  213. return validate_arguments ();
  214. }
  215. int
  216. validate_arguments (void)
  217. {
  218. if (wload1 < 0)
  219. usage (_("Warning threshold for 1-minute load average is not specified\n"));
  220. if (wload5 < 0)
  221. usage (_("Warning threshold for 5-minute load average is not specified\n"));
  222. if (wload15 < 0)
  223. usage (_("Warning threshold for 15-minute load average is not specified\n"));
  224. if (cload1 < 0)
  225. usage (_("Critical threshold for 1-minute load average is not specified\n"));
  226. if (cload5 < 0)
  227. usage (_("Critical threshold for 5-minute load average is not specified\n"));
  228. if (cload15 < 0)
  229. usage (_("Critical threshold for 15-minute load average is not specified\n"));
  230. if (wload1 > cload1)
  231. usage (_("Parameter inconsistency: 1-minute \"warning load\" greater than \"critical load\".\n"));
  232. if (wload5 > cload5)
  233. usage (_("Parameter inconsistency: 5-minute \"warning load\" greater than \"critical load\".\n"));
  234. if (wload15 > cload15)
  235. usage (_("Parameter inconsistency: 15-minute \"warning load\" greater than \"critical load\".\n"));
  236. return OK;
  237. }
  238. void
  239. print_help (void)
  240. {
  241. print_revision (progname, revision);
  242. printf (_("Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>\n"));
  243. printf (_(COPYRIGHT), copyright, email);
  244. printf (_("This plugin tests the current system load average.\n\n"));
  245. print_usage ();
  246. printf (_(UT_HELP_VRSN));
  247. printf (_("\
  248. -w, --warning=WLOAD1,WLOAD5,WLOAD15\n\
  249. Exit with WARNING status if load average exceeds WLOADn\n\
  250. -c, --critical=CLOAD1,CLOAD5,CLOAD15\n\
  251. Exit with CRITICAL status if load average exceed CLOADn\n\n\
  252. the load average format is the same used by \"uptime\" and \"w\"\n\n"));
  253. printf (_(UT_SUPPORT));
  254. }
  255. void
  256. print_usage (void)
  257. {
  258. printf (_("Usage: %s -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n"),
  259. progname);
  260. printf (_(UT_HLP_VRS), progname, progname);
  261. }