diff options
-rw-r--r-- | plugins/check_load.c | 223 |
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 | ||
42 | int process_arguments (int argc, char **argv); | 42 | static int process_arguments (int argc, char **argv); |
43 | int validate_arguments (void); | 43 | static int validate_arguments (void); |
44 | void print_help (void); | 44 | void print_help (void); |
45 | void print_usage (void); | 45 | void print_usage (void); |
46 | 46 | ||
47 | float wload1 = -1, wload5 = -1, wload15 = -1; | 47 | /* strictly for pretty-print usage in loops */ |
48 | float cload1 = -1, cload5 = -1, cload15 = -1; | 48 | static const int nums[3] = { 1, 5, 15 }; |
49 | |||
50 | /* provide some fairly sane defaults */ | ||
51 | double wload[3] = { 0.0, 0.0, 0.0 }; | ||
52 | double 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 | ||
50 | char *status_line; | 57 | char *status_line; |
51 | 58 | ||
59 | static void | ||
60 | get_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 | ||
54 | int | 85 | int |
55 | main (int argc, char **argv) | 86 | main (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 */ |
164 | int | 185 | static int |
165 | process_arguments (int argc, char **argv) | 186 | process_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 | ||
267 | int | 245 | static int |
268 | validate_arguments (void) | 246 | validate_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 | ||