Code

line indentation
[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.
17 ******************************************************************************/
19 const char *progname = "check_load";
20 const char *revision = "$Revision$";
21 const char *copyright = "1999-2003";
22 const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 #include "common.h"
25 #include "utils.h"
26 #include "popen.h"
28 #ifdef HAVE_SYS_LOADAVG_H
29 #include <sys/loadavg.h>
30 #endif
32 /* needed for compilation under NetBSD, as suggested by Andy Doran */
33 #ifndef LOADAVG_1MIN
34 #define LOADAVG_1MIN    0
35 #define LOADAVG_5MIN    1
36 #define LOADAVG_15MIN   2
37 #endif /* !defined LOADAVG_1MIN */
40 int process_arguments (int argc, char **argv);
41 int validate_arguments (void);
42 void print_help (void);
43 void print_usage (void);
45 float wload1 = -1, wload5 = -1, wload15 = -1;
46 float cload1 = -1, cload5 = -1, cload15 = -1;
48 char *status_line;
54 \f
55 int
56 main (int argc, char **argv)
57 {
58         int result;
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) == ERROR)
78                 usage ("failed processing arguments\n");
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              perfdata ("load1", la1, "", wload1, wload1, cload1, cload1, TRUE, 0, FALSE, 0),
156              perfdata ("load5", la5, "", wload5, wload5, cload5, cload5, TRUE, 0, FALSE, 0),
157              perfdata ("load15", la15, "", wload15, wload15, cload15, cload15, TRUE, 0, FALSE, 0));
158         return STATE_OK;
165 \f
166 /* process command-line arguments */
167 int
168 process_arguments (int argc, char **argv)
170         int c = 0;
172         int option = 0;
173         static struct option longopts[] = {
174                 {"warning", required_argument, 0, 'w'},
175                 {"critical", required_argument, 0, 'c'},
176                 {"version", no_argument, 0, 'V'},
177                 {"help", no_argument, 0, 'h'},
178                 {0, 0, 0, 0}
179         };
181         if (argc < 2)
182                 return ERROR;
184         while (1) {
185                 c = getopt_long (argc, argv, "Vhc:w:", longopts, &option);
187                 if (c == -1 || c == EOF)
188                         break;
190                 switch (c) {
191                 case 'w':                                                                       /* warning time threshold */
192                         if (is_intnonneg (optarg)) {
193                                 wload1 = atof (optarg);
194                                 wload5 = atof (optarg);
195                                 wload15 = atof (optarg);
196                                 break;
197                         }
198                         else if (strstr (optarg, ",") &&
199                                                                  sscanf (optarg, "%f,%f,%f", &wload1, &wload5, &wload15) == 3)
200                                 break;
201                         else if (strstr (optarg, ":") &&
202                                                          sscanf (optarg, "%f:%f:%f", &wload1, &wload5, &wload15) == 3)
203                                 break;
204                         else
205                                 usage (_("Warning threshold must be float or float triplet!\n"));
206                         break;
207                 case 'c':                                                                       /* critical time threshold */
208                         if (is_intnonneg (optarg)) {
209                                 cload1 = atof (optarg);
210                                 cload5 = atof (optarg);
211                                 cload15 = atof (optarg);
212                                 break;
213                         }
214                         else if (strstr (optarg, ",") &&
215                                                          sscanf (optarg, "%f,%f,%f", &cload1, &cload5, &cload15) == 3)
216                                 break;
217                         else if (strstr (optarg, ":") &&
218                                                          sscanf (optarg, "%f:%f:%f", &cload1, &cload5, &cload15) == 3)
219                                 break;
220                         else
221                                 usage (_("Critical threshold must be float or float triplet!\n"));
222                         break;
223                 case 'V':                                                                       /* version */
224                         print_revision (progname, "$Revision$");
225                         exit (STATE_OK);
226                 case 'h':                                                                       /* help */
227                         print_help ();
228                         exit (STATE_OK);
229                 case '?':                                                                       /* help */
230                         usage (_("Invalid argument\n"));
231                 }
232         }
234         c = optind;
235         if (c == argc)
236                 return validate_arguments ();
237         if (wload1 < 0 && is_nonnegative (argv[c]))
238                 wload1 = atof (argv[c++]);
240         if (c == argc)
241                 return validate_arguments ();
242         if (cload1 < 0 && is_nonnegative (argv[c]))
243                 cload1 = atof (argv[c++]);
245         if (c == argc)
246                 return validate_arguments ();
247         if (wload5 < 0 && is_nonnegative (argv[c]))
248                 wload5 = atof (argv[c++]);
250         if (c == argc)
251                 return validate_arguments ();
252         if (cload5 < 0 && is_nonnegative (argv[c]))
253                 cload5 = atof (argv[c++]);
255         if (c == argc)
256                 return validate_arguments ();
257         if (wload15 < 0 && is_nonnegative (argv[c]))
258                 wload15 = atof (argv[c++]);
260         if (c == argc)
261                 return validate_arguments ();
262         if (cload15 < 0 && is_nonnegative (argv[c]))
263                 cload15 = atof (argv[c++]);
265         return validate_arguments ();
272 int
273 validate_arguments (void)
275         if (wload1 < 0)
276                 usage (_("Warning threshold for 1-minute load average is not specified\n"));
277         if (wload5 < 0)
278                 usage (_("Warning threshold for 5-minute load average is not specified\n"));
279         if (wload15 < 0)
280                 usage (_("Warning threshold for 15-minute load average is not specified\n"));
281         if (cload1 < 0)
282                 usage (_("Critical threshold for 1-minute load average is not specified\n"));
283         if (cload5 < 0)
284                 usage (_("Critical threshold for 5-minute load average is not specified\n"));
285         if (cload15 < 0)
286                 usage (_("Critical threshold for 15-minute load average is not specified\n"));
287         if (wload1 > cload1)
288                 usage (_("Parameter inconsistency: 1-minute \"warning load\" greater than \"critical load\".\n"));
289         if (wload5 > cload5)
290                 usage (_("Parameter inconsistency: 5-minute \"warning load\" greater than \"critical load\".\n"));
291         if (wload15 > cload15)
292                 usage (_("Parameter inconsistency: 15-minute \"warning load\" greater than \"critical load\".\n"));
293         return OK;
300 \f
301 void
302 print_help (void)
304         print_revision (progname, revision);
306         printf (_("Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>\n"));
307         printf (_(COPYRIGHT), copyright, email);
309         printf (_("This plugin tests the current system load average.\n\n"));
311         print_usage ();
313         printf (_(UT_HELP_VRSN));
315         printf (_("\
316  -w, --warning=WLOAD1,WLOAD5,WLOAD15\n\
317    Exit with WARNING status if load average exceeds WLOADn\n\
318  -c, --critical=CLOAD1,CLOAD5,CLOAD15\n\
319    Exit with CRITICAL status if load average exceed CLOADn\n\n\
320 the load average format is the same used by \"uptime\" and \"w\"\n\n"));
322         printf (_(UT_SUPPORT));
325 void
326 print_usage (void)
328         printf (_("Usage: %s -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n"),
329                 progname);
330         printf (_(UT_HLP_VRS), progname, progname);