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