summaryrefslogtreecommitdiffstats
path: root/plugins/check_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_load.c')
-rw-r--r--plugins/check_load.c223
1 files changed, 98 insertions, 125 deletions
diff --git a/plugins/check_load.c b/plugins/check_load.c
index 7e1cc48..9625036 100644
--- a/plugins/check_load.c
+++ b/plugins/check_load.c
@@ -39,37 +39,64 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
39#endif /* !defined LOADAVG_1MIN */ 39#endif /* !defined LOADAVG_1MIN */
40 40
41 41
42int process_arguments (int argc, char **argv); 42static int process_arguments (int argc, char **argv);
43int validate_arguments (void); 43static int validate_arguments (void);
44void print_help (void); 44void print_help (void);
45void print_usage (void); 45void print_usage (void);
46 46
47float wload1 = -1, wload5 = -1, wload15 = -1; 47/* strictly for pretty-print usage in loops */
48float cload1 = -1, cload5 = -1, cload15 = -1; 48static const int nums[3] = { 1, 5, 15 };
49
50/* provide some fairly sane defaults */
51double wload[3] = { 0.0, 0.0, 0.0 };
52double cload[3] = { 0.0, 0.0, 0.0 };
53#define la1 la[0]
54#define la5 la[1]
55#define la15 la[2]
49 56
50char *status_line; 57char *status_line;
51 58
59static void
60get_threshold(char *arg, double *th)
61{
62 size_t i, n;
63 char *str = arg, *p;
64
65 n = strlen(arg);
66 for(i = 0; i < 3; i++) {
67 th[i] = strtod(str, &p);
68 if(p == str) break;
69
70 str = p + 1;
71 if(n <= (size_t)(str - arg)) break;
72 }
73
74 /* empty argument or non-floatish, so warn about it and die */
75 if(!i) usage (_("Warning threshold must be float or float triplet!\n"));
76
77 if(i != 2) {
78 /* one or more numbers were given, so fill array with last
79 * we got (most likely to NOT produce the least expected result) */
80 for(n = i; n < 3; n++) th[n] = th[i];
81 }
82}
52 83
53 84
54int 85int
55main (int argc, char **argv) 86main (int argc, char **argv)
56{ 87{
57 int result = STATE_UNKNOWN; 88 int result;
58 89 int i;
59#if HAVE_GETLOADAVG==1 90
60 double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about unitialized arrays */ 91 double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about unitialized arrays */
61#else 92#ifndef HAVE_GETLOADAVG
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]; 93 char input_buffer[MAX_INPUT_BUFFER];
94# ifdef HAVE_PROC_LOADAVG
95 FILE *fp;
96 char *str, *next;
68# endif 97# endif
69#endif 98#endif
70 99
71 float la1, la5, la15;
72
73 setlocale (LC_ALL, ""); 100 setlocale (LC_ALL, "");
74 bindtextdomain (PACKAGE, LOCALEDIR); 101 bindtextdomain (PACKAGE, LOCALEDIR);
75 textdomain (PACKAGE); 102 textdomain (PACKAGE);
@@ -77,30 +104,24 @@ main (int argc, char **argv)
77 if (process_arguments (argc, argv) == ERROR) 104 if (process_arguments (argc, argv) == ERROR)
78 usage4 (_("Could not parse arguments")); 105 usage4 (_("Could not parse arguments"));
79 106
80#if HAVE_GETLOADAVG==1 107#ifdef HAVE_GETLOADAVG
81 result = getloadavg (la, 3); 108 result = getloadavg (la, 3);
82 if (result == -1) 109 if (result != 3)
83 return STATE_UNKNOWN; 110 return STATE_UNKNOWN;
84 la1 = la[LOADAVG_1MIN];
85 la5 = la[LOADAVG_5MIN];
86 la15 = la[LOADAVG_15MIN];
87#else 111#else
88# if HAVE_PROC_LOADAVG==1 112# ifdef HAVE_PROC_LOADAVG
89 fp = fopen (PROC_LOADAVG, "r"); 113 fp = fopen (PROC_LOADAVG, "r");
90 if (fp == NULL) { 114 if (fp == NULL) {
91 printf (_("Error opening %s\n"), PROC_LOADAVG); 115 printf (_("Error opening %s\n"), PROC_LOADAVG);
92 return STATE_UNKNOWN; 116 return STATE_UNKNOWN;
93 } 117 }
94 118
95 la1 = la5 = la15 = -1;
96
97 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { 119 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
98 tmp_ptr = strtok (input_buffer, " "); 120 str = (char *)input_buffer;
99 la1 = atof (tmp_ptr); 121 for(i = 0; i < 3; i++) {
100 tmp_ptr = strtok (NULL, " "); 122 la[i] = strtod(str, &next);
101 la5 = atof (tmp_ptr); 123 str = next;
102 tmp_ptr = strtok (NULL, " "); 124 }
103 la15 = atof (tmp_ptr);
104 } 125 }
105 126
106 fclose (fp); 127 fclose (fp);
@@ -125,12 +146,11 @@ main (int argc, char **argv)
125# endif 146# endif
126#endif 147#endif
127 148
128 149 if ((la[0] < 0.0) || (la[1] < 0.0) || (la[2] < 0.0)) {
129 if ((la1 < 0.0) || (la5 < 0.0) || (la15 < 0.0)) { 150#ifdef HAVE_GETLOADAVG
130#if HAVE_GETLOADAVG==1
131 printf (_("Error in getloadavg()\n")); 151 printf (_("Error in getloadavg()\n"));
132#else 152#else
133# if HAVE_PROC_LOADAVG==1 153# ifdef HAVE_PROC_LOADAVG
134 printf (_("Error processing %s\n"), PROC_LOADAVG); 154 printf (_("Error processing %s\n"), PROC_LOADAVG);
135# else 155# else
136 printf (_("Error processing %s\n"), PATH_TO_UPTIME); 156 printf (_("Error processing %s\n"), PATH_TO_UPTIME);
@@ -139,29 +159,30 @@ main (int argc, char **argv)
139 return STATE_UNKNOWN; 159 return STATE_UNKNOWN;
140 } 160 }
141 161
162 /* we got this far, so assume OK until we've measured */
163 result = STATE_OK;
164
142 asprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15); 165 asprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15);
143 166
144 if ((la1 >= cload1) || (la5 >= cload5) || (la15 >= cload15)) 167 for(i = 0; i < 3; i++) {
145 result = STATE_CRITICAL; 168 if(la[i] > cload[i]) {
146 else if ((la1 >= wload1) || (la5 >= wload5) || (la15 >= wload15)) 169 result = STATE_CRITICAL;
147 result = STATE_WARNING; 170 break;
148 else 171 }
149 result = STATE_OK; 172 else if(la[i] > wload[i]) result = STATE_WARNING;
150 173 }
151 die (result, 174
152 "%s - %s|%s %s %s\n", 175 printf("%s - %s|", state_text(result), status_line);
153 state_text (result), 176 for(i = 0; i < 3; i++)
154 status_line, 177 printf("load%d=%.3f;%.3f;%.3f;0; ", nums[i], la[i], wload[i], cload[i]);
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}
160 178
179 putchar('\n');
180 return result;
181}
161 182
162 183
163/* process command-line arguments */ 184/* process command-line arguments */
164int 185static int
165process_arguments (int argc, char **argv) 186process_arguments (int argc, char **argv)
166{ 187{
167 int c = 0; 188 int c = 0;
@@ -185,37 +206,11 @@ process_arguments (int argc, char **argv)
185 break; 206 break;
186 207
187 switch (c) { 208 switch (c) {
188 case 'w': /* warning time threshold */ 209 case 'w': /* warning time threshold */
189 if (is_intnonneg (optarg)) { 210 get_threshold(optarg, wload);
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; 211 break;
204 case 'c': /* critical time threshold */ 212 case 'c': /* critical time threshold */
205 if (is_intnonneg (optarg)) { 213 get_threshold(optarg, cload);
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; 214 break;
220 case 'V': /* version */ 215 case 'V': /* version */
221 print_revision (progname, revision); 216 print_revision (progname, revision);
@@ -231,60 +226,38 @@ process_arguments (int argc, char **argv)
231 c = optind; 226 c = optind;
232 if (c == argc) 227 if (c == argc)
233 return validate_arguments (); 228 return validate_arguments ();
234 if (wload1 < 0 && is_nonnegative (argv[c]))
235 wload1 = atof (argv[c++]);
236
237 if (c == argc)
238 return validate_arguments ();
239 if (cload1 < 0 && is_nonnegative (argv[c]))
240 cload1 = atof (argv[c++]);
241
242 if (c == argc)
243 return validate_arguments ();
244 if (wload5 < 0 && is_nonnegative (argv[c]))
245 wload5 = atof (argv[c++]);
246 229
247 if (c == argc) 230 /* handle the case if both arguments are missing,
248 return validate_arguments (); 231 * but not if only one is given without -c or -w flag */
249 if (cload5 < 0 && is_nonnegative (argv[c])) 232 if(c - argc == 2) {
250 cload5 = atof (argv[c++]); 233 get_threshold(argv[c++], wload);
251 234 get_threshold(argv[c++], cload);
252 if (c == argc) 235 }
253 return validate_arguments (); 236 else if(c - argc == 1) {
254 if (wload15 < 0 && is_nonnegative (argv[c])) 237 get_threshold(argv[c++], cload);
255 wload15 = atof (argv[c++]); 238 }
256
257 if (c == argc)
258 return validate_arguments ();
259 if (cload15 < 0 && is_nonnegative (argv[c]))
260 cload15 = atof (argv[c++]);
261 239
262 return validate_arguments (); 240 return validate_arguments ();
263} 241}
264 242
265 243
266 244
267int 245static int
268validate_arguments (void) 246validate_arguments (void)
269{ 247{
270 if (wload1 < 0) 248 int i = 0;
271 usage (_("Warning threshold for 1-minute load average is not specified\n")); 249
272 if (wload5 < 0) 250 /* match cload first, as it will give the most friendly error message
273 usage (_("Warning threshold for 5-minute load average is not specified\n")); 251 * if user hasn't given the -c switch properly */
274 if (wload15 < 0) 252 for(i = 0; i < 3; i++) {
275 usage (_("Warning threshold for 15-minute load average is not specified\n")); 253 if(cload[i] < 0)
276 if (cload1 < 0) 254 die (STATE_UNKNOWN, _("Critical threshold for %d-minute load average is not specified\n"), nums[i]);
277 usage (_("Critical threshold for 1-minute load average is not specified\n")); 255 if(wload[i] < 0)
278 if (cload5 < 0) 256 die (STATE_UNKNOWN, _("Warning threshold for %d-minute load average is not specified\n"), nums[i]);
279 usage (_("Critical threshold for 5-minute load average is not specified\n")); 257 if(wload[i] > cload[i])
280 if (cload15 < 0) 258 die (STATE_UNKNOWN, _("Parameter inconsistency: %d-minute \"warning load\" is greater than \"critical load\"\n"), nums[i]);
281 usage (_("Critical threshold for 15-minute load average is not specified\n")); 259 }
282 if (wload1 > cload1) 260
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; 261 return OK;
289} 262}
290 263