Code

6d87237f5ce4aaa70772505769d2ab2077fabd38
[nagiosplug.git] / plugins / check_load.c
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.
16  
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;
58         
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;
163 /* process command-line arguments */
164 int
165 process_arguments (int argc, char **argv)
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 ();
269 int
270 validate_arguments (void)
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;
295 void
296 print_help (void)
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));
319 void
320 print_usage (void)
322         printf ("Usage: %s -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n"),
323                 progname);
324                                         
325         printf (UT_HLP_VRS, progname, progname);