Code

7e1cc481e9d777b3662cf404c9f65c6322f9d6eb
[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) == ERROR)
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                         usage2 (_("Unknown argument"), optarg);
228                 }
229         }
231         c = optind;
232         if (c == argc)
233                 return validate_arguments ();
234         if (wload1 < 0 && is_nonnegative (argv[c]))
235                 wload1 = atof (argv[c++]);
237         if (c == argc)
238                 return validate_arguments ();
239         if (cload1 < 0 && is_nonnegative (argv[c]))
240                 cload1 = atof (argv[c++]);
242         if (c == argc)
243                 return validate_arguments ();
244         if (wload5 < 0 && is_nonnegative (argv[c]))
245                 wload5 = atof (argv[c++]);
247         if (c == argc)
248                 return validate_arguments ();
249         if (cload5 < 0 && is_nonnegative (argv[c]))
250                 cload5 = atof (argv[c++]);
252         if (c == argc)
253                 return validate_arguments ();
254         if (wload15 < 0 && is_nonnegative (argv[c]))
255                 wload15 = atof (argv[c++]);
257         if (c == argc)
258                 return validate_arguments ();
259         if (cload15 < 0 && is_nonnegative (argv[c]))
260                 cload15 = atof (argv[c++]);
262         return validate_arguments ();
267 int
268 validate_arguments (void)
270         if (wload1 < 0)
271                 usage (_("Warning threshold for 1-minute load average is not specified\n"));
272         if (wload5 < 0)
273                 usage (_("Warning threshold for 5-minute load average is not specified\n"));
274         if (wload15 < 0)
275                 usage (_("Warning threshold for 15-minute load average is not specified\n"));
276         if (cload1 < 0)
277                 usage (_("Critical threshold for 1-minute load average is not specified\n"));
278         if (cload5 < 0)
279                 usage (_("Critical threshold for 5-minute load average is not specified\n"));
280         if (cload15 < 0)
281                 usage (_("Critical threshold for 15-minute load average is not specified\n"));
282         if (wload1 > cload1)
283                 usage (_("Parameter inconsistency: 1-minute \"warning load\" greater than \"critical load\".\n"));
284         if (wload5 > cload5)
285                 usage (_("Parameter inconsistency: 5-minute \"warning load\" greater than \"critical load\".\n"));
286         if (wload15 > cload15)
287                 usage (_("Parameter inconsistency: 15-minute \"warning load\" greater than \"critical load\".\n"));
288         return OK;
293 void
294 print_help (void)
296         print_revision (progname, revision);
298         printf ("Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>\n");
299         printf (COPYRIGHT, copyright, email);
301         printf (_("This plugin tests the current system load average.\n\n"));
303         print_usage ();
305         printf (_(UT_HELP_VRSN));
307         printf (_("\
308  -w, --warning=WLOAD1,WLOAD5,WLOAD15\n\
309    Exit with WARNING status if load average exceeds WLOADn\n\
310  -c, --critical=CLOAD1,CLOAD5,CLOAD15\n\
311    Exit with CRITICAL status if load average exceed CLOADn\n\n\
312 the load average format is the same used by \"uptime\" and \"w\"\n\n"));
314         printf (_(UT_SUPPORT));
317 void
318 print_usage (void)
320         printf ("Usage: %s -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n", progname);