summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTon Voon <tonvoon@users.sourceforge.net>2008-03-19 14:42:12 +0000
committerTon Voon <tonvoon@users.sourceforge.net>2008-03-19 14:42:12 +0000
commitb17b2421987bb8a7606948333e75f990b35852b8 (patch)
tree5d220f355728f1448f9dbd6f796631bbfef0733c
parentcab9440a671390e279228cd31ad56b055d611a21 (diff)
downloadmonitoring-plugins-b17b2421987bb8a7606948333e75f990b35852b8.tar.gz
1st pass at check_procs with multiple threshold checks
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/branches/new_threshold_syntax@1958 f882894a-f735-0410-b71e-b25c423dba1c
-rw-r--r--lib/tests/test_utils.c158
-rw-r--r--lib/utils_base.c135
-rw-r--r--lib/utils_base.h21
-rw-r--r--plugins/check_cluster.c2
-rw-r--r--plugins/check_procs.c238
5 files changed, 477 insertions, 77 deletions
diff --git a/lib/tests/test_utils.c b/lib/tests/test_utils.c
index 278f526e..a5189cea 100644
--- a/lib/tests/test_utils.c
+++ b/lib/tests/test_utils.c
@@ -30,7 +30,7 @@ main (int argc, char **argv)
30 thresholds *thresholds = NULL; 30 thresholds *thresholds = NULL;
31 int rc; 31 int rc;
32 32
33 plan_tests(82); 33 plan_tests(172);
34 34
35 range = parse_range_string("6"); 35 range = parse_range_string("6");
36 ok( range != NULL, "'6' is valid range"); 36 ok( range != NULL, "'6' is valid range");
@@ -40,6 +40,32 @@ main (int argc, char **argv)
40 ok( range->end_infinity == FALSE, "Not using infinity"); 40 ok( range->end_infinity == FALSE, "Not using infinity");
41 free(range); 41 free(range);
42 42
43 range = _parse_range_string_v2("6");
44 ok( range == NULL, "Missing colon in range" );
45 ok( utils_errno == NP_RANGE_MISSING_COLON, "Right error code" );
46
47 range = _parse_range_string_v2("6:");
48 ok( range != NULL, "'6:' is valid range");
49 ok( range->start == 6, "Start correct");
50 ok( range->start_infinity == FALSE, "Not using negative infinity");
51 ok( range->end_infinity == TRUE, "Using infinity");
52 free(range);
53
54 range = _parse_range_string_v2("6:6");
55 ok( range != NULL, "'6:6' is valid range");
56 ok( range->start == 6, "Start correct");
57 ok( range->start_infinity == FALSE, "Not using negative infinity");
58 ok( range->end == 6, "End correct");
59 ok( range->end_infinity == FALSE, "Not using infinity");
60 free(range);
61
62 range = _parse_range_string_v2(":6");
63 ok( range != NULL, "':6' is valid range");
64 ok( range->start_infinity == TRUE, "Using negative infinity");
65 ok( range->end == 6, "End correct");
66 ok( range->end_infinity == FALSE, "Not using infinity");
67 free(range);
68
43 range = parse_range_string("1:12%%"); 69 range = parse_range_string("1:12%%");
44 ok( range != NULL, "'1:12%%' is valid - percentages are ignored"); 70 ok( range != NULL, "'1:12%%' is valid - percentages are ignored");
45 ok( range->start == 1, "Start correct"); 71 ok( range->start == 1, "Start correct");
@@ -48,6 +74,14 @@ main (int argc, char **argv)
48 ok( range->end_infinity == FALSE, "Not using infinity"); 74 ok( range->end_infinity == FALSE, "Not using infinity");
49 free(range); 75 free(range);
50 76
77 range = _parse_range_string_v2("1:12%%");
78 ok( range != NULL, "'1:12%%' is valid - percentages are ignored");
79 ok( range->start == 1, "Start correct");
80 ok( range->start_infinity == FALSE, "Not using negative infinity");
81 ok( range->end == 12, "End correct");
82 ok( range->end_infinity == FALSE, "Not using infinity");
83 free(range);
84
51 range = parse_range_string("-7:23"); 85 range = parse_range_string("-7:23");
52 ok( range != NULL, "'-7:23' is valid range"); 86 ok( range != NULL, "'-7:23' is valid range");
53 ok( range->start == -7, "Start correct"); 87 ok( range->start == -7, "Start correct");
@@ -56,6 +90,14 @@ main (int argc, char **argv)
56 ok( range->end_infinity == FALSE, "Not using infinity"); 90 ok( range->end_infinity == FALSE, "Not using infinity");
57 free(range); 91 free(range);
58 92
93 range = _parse_range_string_v2("-7:23");
94 ok( range != NULL, "'-7:23' is valid range");
95 ok( range->start == -7, "Start correct");
96 ok( range->start_infinity == FALSE, "Not using negative infinity");
97 ok( range->end == 23, "End correct");
98 ok( range->end_infinity == FALSE, "Not using infinity");
99 free(range);
100
59 range = parse_range_string(":5.75"); 101 range = parse_range_string(":5.75");
60 ok( range != NULL, "':5.75' is valid range"); 102 ok( range != NULL, "':5.75' is valid range");
61 ok( range->start == 0, "Start correct"); 103 ok( range->start == 0, "Start correct");
@@ -64,6 +106,14 @@ main (int argc, char **argv)
64 ok( range->end_infinity == FALSE, "Not using infinity"); 106 ok( range->end_infinity == FALSE, "Not using infinity");
65 free(range); 107 free(range);
66 108
109 range = _parse_range_string_v2(":5.75");
110 ok( range != NULL, "':5.75' is valid range");
111 ok( range->start == 0, "Start correct");
112 ok( range->start_infinity == TRUE, "Using negative infinity");
113 ok( range->end == 5.75, "End correct");
114 ok( range->end_infinity == FALSE, "Not using infinity");
115 free(range);
116
67 range = parse_range_string("~:-95.99"); 117 range = parse_range_string("~:-95.99");
68 ok( range != NULL, "~:-95.99' is valid range"); 118 ok( range != NULL, "~:-95.99' is valid range");
69 ok( range->start_infinity == TRUE, "Using negative infinity"); 119 ok( range->start_infinity == TRUE, "Using negative infinity");
@@ -71,6 +121,26 @@ main (int argc, char **argv)
71 ok( range->end_infinity == FALSE, "Not using infinity"); 121 ok( range->end_infinity == FALSE, "Not using infinity");
72 free(range); 122 free(range);
73 123
124 range = _parse_range_string_v2("~:-95.99");
125 ok( range == NULL, "~:-95.99' is invalid range");
126 ok( utils_errno == NP_RANGE_UNPARSEABLE, "Correct error code" );
127
128 /*
129 * This is currently parseable. This is because ~ is interpreted as a 0
130 * and then 95.99 is the end, so we get 0:95.99. Should validate the characters before
131 * passing to strtod
132 range = _parse_range_string_v2("~:95.99");
133 ok( range == NULL, "~:95.99' is invalid range");
134 ok( utils_errno == NP_RANGE_UNPARSEABLE, "Correct error code" );
135 */
136
137 range = _parse_range_string_v2(":-95.99");
138 ok( range != NULL, ":-95.99' is valid range");
139 ok( range->start_infinity == TRUE, "Using negative infinity");
140 ok( range->end == -95.99, "End correct (with rounding errors)");
141 ok( range->end_infinity == FALSE, "Not using infinity");
142 free(range);
143
74 range = parse_range_string("12345678901234567890:"); 144 range = parse_range_string("12345678901234567890:");
75 temp = atof("12345678901234567890"); /* Can't just use this because number too large */ 145 temp = atof("12345678901234567890"); /* Can't just use this because number too large */
76 ok( range != NULL, "'12345678901234567890:' is valid range"); 146 ok( range != NULL, "'12345678901234567890:' is valid range");
@@ -83,6 +153,14 @@ main (int argc, char **argv)
83 ok( check_range(temp*2, range) == FALSE, "12345678901234567890*2 - no alert"); 153 ok( check_range(temp*2, range) == FALSE, "12345678901234567890*2 - no alert");
84 free(range); 154 free(range);
85 155
156 range = _parse_range_string_v2("12345678901234567890:");
157 temp = atof("12345678901234567890");
158 ok( range != NULL, "'12345678901234567890:' is valid range");
159 ok( range->start == temp, "Start correct");
160 ok( range->start_infinity == FALSE, "Not using negative infinity");
161 ok( range->end_infinity == TRUE, "Using infinity");
162 free(range);
163
86 range = parse_range_string("~:0"); 164 range = parse_range_string("~:0");
87 ok( range != NULL, "'~:0' is valid range"); 165 ok( range != NULL, "'~:0' is valid range");
88 ok( range->start_infinity == TRUE, "Using negative infinity"); 166 ok( range->start_infinity == TRUE, "Using negative infinity");
@@ -94,8 +172,16 @@ main (int argc, char **argv)
94 ok( check_range(0, range) == FALSE, "0 - no alert"); 172 ok( check_range(0, range) == FALSE, "0 - no alert");
95 free(range); 173 free(range);
96 174
175 range = _parse_range_string_v2("-4.33:-4.33");
176 ok( range != NULL, "'-4.33:-4.33' is valid range");
177 ok( range->start_infinity == FALSE, "Not using negative infinity");
178 ok( range->start == -4.33, "Start right");
179 ok( range->end == -4.33, "End correct");
180 ok( range->end_infinity == FALSE, "Not using infinity");
181 free(range);
182
97 range = parse_range_string("@0:657.8210567"); 183 range = parse_range_string("@0:657.8210567");
98 ok( range != 0, "@0:657.8210567' is a valid range"); 184 ok( range != NULL, "@0:657.8210567' is a valid range");
99 ok( range->start == 0, "Start correct"); 185 ok( range->start == 0, "Start correct");
100 ok( range->start_infinity == FALSE, "Not using negative infinity"); 186 ok( range->start_infinity == FALSE, "Not using negative infinity");
101 ok( range->end == 657.8210567, "End correct"); 187 ok( range->end == 657.8210567, "End correct");
@@ -107,6 +193,14 @@ main (int argc, char **argv)
107 ok( check_range(0, range) == TRUE, "0 - alert"); 193 ok( check_range(0, range) == TRUE, "0 - alert");
108 free(range); 194 free(range);
109 195
196 range = parse_range_string("^0:657.8210567");
197 ok( range != NULL, "^0:657.8210567' is a valid range");
198 ok( range->start == 0, "Start correct");
199 ok( range->start_infinity == FALSE, "Not using negative infinity");
200 ok( range->end == 657.8210567, "End correct");
201 ok( range->end_infinity == FALSE, "Not using infinity");
202 free(range);
203
110 range = parse_range_string("1:1"); 204 range = parse_range_string("1:1");
111 ok( range != NULL, "'1:1' is a valid range"); 205 ok( range != NULL, "'1:1' is a valid range");
112 ok( range->start == 1, "Start correct"); 206 ok( range->start == 1, "Start correct");
@@ -121,22 +215,71 @@ main (int argc, char **argv)
121 range = parse_range_string("2:1"); 215 range = parse_range_string("2:1");
122 ok( range == NULL, "'2:1' rejected"); 216 ok( range == NULL, "'2:1' rejected");
123 217
218 range = _parse_range_string_v2("2:1");
219 ok( range == NULL, "'2:1' rejected");
220 ok( utils_errno == NP_RANGE_UNPARSEABLE, "Errno correct" );
221
124 rc = _set_thresholds(&thresholds, NULL, NULL); 222 rc = _set_thresholds(&thresholds, NULL, NULL);
125 ok( rc == 0, "Thresholds (NULL, NULL) set"); 223 ok( rc == 0, "Thresholds (NULL, NULL) set");
126 ok( thresholds->warning == NULL, "Warning not set"); 224 ok( thresholds->warning == NULL, "Warning not set");
127 ok( thresholds->critical == NULL, "Critical not set"); 225 ok( thresholds->critical == NULL, "Critical not set");
128 226
227 thresholds = _parse_thresholds_string(NULL);
228 ok( thresholds != NULL, "Threshold still set, even though NULL");
229 ok( thresholds->warning == NULL, "Warning set to NULL");
230 ok( thresholds->critical == NULL, "Critical set to NULL");
231
232 thresholds = _parse_thresholds_string("");
233 ok( thresholds != NULL, "Threshold still set, even though ''");
234 ok( thresholds->warning == NULL, "Warning set to NULL");
235 ok( thresholds->critical == NULL, "Critical set to NULL");
236
237 thresholds = _parse_thresholds_string("/");
238 ok( thresholds != NULL, "Threshold still set, even though '/'");
239 ok( thresholds->warning == NULL, "Warning set to NULL");
240 ok( thresholds->critical == NULL, "Critical set to NULL");
241
129 rc = _set_thresholds(&thresholds, NULL, "80"); 242 rc = _set_thresholds(&thresholds, NULL, "80");
130 ok( rc == 0, "Thresholds (NULL, '80') set"); 243 ok( rc == 0, "Thresholds (NULL, '80') set");
131 ok( thresholds->warning == NULL, "Warning not set"); 244 ok( thresholds->warning == NULL, "Warning not set");
132 ok( thresholds->critical->end == 80, "Critical set correctly"); 245 ok( thresholds->critical->end == 80, "Critical set correctly");
133 246
247 thresholds = _parse_thresholds_string(":80/");
248 ok( thresholds != NULL, "Threshold set for ':80/'");
249 ok( thresholds->warning == NULL, "Warning set to NULL");
250 ok( thresholds->critical->start_infinity == TRUE, "Start is right" );
251 ok( thresholds->critical->end == 80, "Critical set to 80");
252
253 thresholds = _parse_thresholds_string(":80");
254 ok( thresholds != NULL, "Threshold set for ':80'");
255 ok( thresholds->warning == NULL, "Warning set to NULL");
256 ok( thresholds->critical->start_infinity == TRUE, "Start is right" );
257 ok( thresholds->critical->end == 80, "Critical set to 80");
258
259 thresholds = _parse_thresholds_string("80");
260 ok( thresholds == NULL, "Threshold not set because of single value '80'");
261 ok( utils_errno == NP_RANGE_MISSING_COLON, "Correct error message");
262
134 rc = _set_thresholds(&thresholds, "5:33", NULL); 263 rc = _set_thresholds(&thresholds, "5:33", NULL);
135 ok( rc == 0, "Thresholds ('5:33', NULL) set"); 264 ok( rc == 0, "Thresholds ('5:33', NULL) set");
136 ok( thresholds->warning->start == 5, "Warning start set"); 265 ok( thresholds->warning->start == 5, "Warning start set");
137 ok( thresholds->warning->end == 33, "Warning end set"); 266 ok( thresholds->warning->end == 33, "Warning end set");
138 ok( thresholds->critical == NULL, "Critical not set"); 267 ok( thresholds->critical == NULL, "Critical not set");
139 268
269 thresholds = _parse_thresholds_string("5:33");
270 ok( thresholds != NULL, "Threshold set for '5:33'");
271 ok( thresholds->warning == NULL, "Warning set to NULL");
272 ok( thresholds->critical->start_infinity == FALSE, "Start is right" );
273 ok( thresholds->critical->start == 5, "Critical set to 5");
274 ok( thresholds->critical->end == 33, "Critical set to 33");
275
276 thresholds = _parse_thresholds_string("/5:33");
277 ok( thresholds != NULL, "Threshold set for '/5:33'");
278 ok( thresholds->critical == NULL, "Critical set to NULL");
279 ok( thresholds->warning->start_infinity == FALSE, "Start is right" );
280 ok( thresholds->warning->start == 5, "Warning start set to 5");
281 ok( thresholds->warning->end == 33, "Warning end set to 33");
282
140 rc = _set_thresholds(&thresholds, "30", "60"); 283 rc = _set_thresholds(&thresholds, "30", "60");
141 ok( rc == 0, "Thresholds ('30', '60') set"); 284 ok( rc == 0, "Thresholds ('30', '60') set");
142 ok( thresholds->warning->end == 30, "Warning set correctly"); 285 ok( thresholds->warning->end == 30, "Warning set correctly");
@@ -145,6 +288,17 @@ main (int argc, char **argv)
145 ok( get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning"); 288 ok( get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning");
146 ok( get_status(69, thresholds) == STATE_CRITICAL, "69 - critical"); 289 ok( get_status(69, thresholds) == STATE_CRITICAL, "69 - critical");
147 290
291 thresholds = _parse_thresholds_string("-6.7:29 / 235.4:3333.33");
292 ok( thresholds != NULL, "Threshold set for '-6.7:29 / 235.4:3333.33'");
293 ok( thresholds->critical->start_infinity == FALSE, "Critical not starting at infinity");
294 ok( thresholds->critical->start == -6.7, "Critical start right" );
295 ok( thresholds->critical->end_infinity == FALSE, "Critical not ending at infinity");
296 ok( thresholds->critical->end == 29, "Critical end right" );
297 ok( thresholds->warning->start_infinity == FALSE, "Start is right" );
298 ok( thresholds->warning->start == 235.4, "Warning set to 5");
299 ok( thresholds->warning->end_infinity == FALSE, "End is right" );
300 ok( thresholds->warning->end == 3333.33, "Warning set to 33");
301
148 char *test; 302 char *test;
149 test = np_escaped_string("bob\\n"); 303 test = np_escaped_string("bob\\n");
150 ok( strcmp(test, "bob\n") == 0, "bob\\n ok"); 304 ok( strcmp(test, "bob\n") == 0, "bob\\n ok");
diff --git a/lib/utils_base.c b/lib/utils_base.c
index d1453c67..1320b712 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -98,6 +98,138 @@ range
98 return NULL; 98 return NULL;
99} 99}
100 100
101/* New range string parsing routines, for the v2 thresholds syntax */
102/* Returns range if OK, otherwise errors. Sets utils_errno if error */
103int utils_errno;
104range *
105_parse_range_string_v2 (char *str) {
106 range *temp_range;
107 double start;
108 double end;
109 char *end_str;
110
111 temp_range = (range *) malloc(sizeof(range));
112
113 /* Initialise */
114 temp_range->start = 0;
115 temp_range->start_infinity = FALSE;
116 temp_range->end = 0;
117 temp_range->end_infinity = FALSE;
118 temp_range->alert_on = INSIDE;
119
120 if (str[0] == '^') {
121 temp_range->alert_on = OUTSIDE;
122 str++;
123 }
124
125 end_str = index(str, ':');
126 if (end_str == NULL) {
127 utils_errno = NP_RANGE_MISSING_COLON;
128 free(temp_range);
129 temp_range = NULL;
130 return NULL;
131 }
132 end_str++;
133 if (str[0] == ':') {
134 temp_range->start_infinity = TRUE;
135 } else {
136 start = strtod(str, NULL); /* Will stop at ':' */
137 set_range_start(temp_range, start);
138 }
139 if (strcmp(end_str, "") != 0) {
140 end = strtod(end_str, NULL);
141 set_range_end(temp_range, end);
142 } else {
143 temp_range->end_infinity = TRUE;
144 }
145
146 if (temp_range->start_infinity == TRUE ||
147 temp_range->end_infinity == TRUE ||
148 temp_range->start <= temp_range->end) {
149 return temp_range;
150 }
151 free(temp_range);
152 temp_range = NULL;
153 utils_errno = NP_RANGE_UNPARSEABLE;
154 return NULL;
155}
156
157void
158_die_on_parse_error(int errorcode) {
159 switch (errorcode) {
160 case NP_RANGE_UNPARSEABLE:
161 die(STATE_UNKNOWN, _("Range format incorrect\n"));
162 case NP_WARN_WITHIN_CRIT:
163 die(STATE_UNKNOWN, _("Warning level is a subset of critical and will not be alerted\n"));
164 case NP_RANGE_MISSING_COLON:
165 die(STATE_UNKNOWN, _("Range is missing a colon\n"));
166 case NP_MEMORY_ERROR:
167 die(STATE_UNKNOWN, _("Memory error\n"));
168 }
169}
170
171thresholds
172*_parse_thresholds_string(char *string) {
173 thresholds *temp_thresholds = NULL;
174 char *separator = NULL;
175 char *temp_string = NULL;
176 range *temp_range = NULL;
177 int rc;
178
179 temp_thresholds = malloc(sizeof(temp_thresholds));
180 if (temp_thresholds == NULL) {
181 utils_errno = NP_MEMORY_ERROR;
182 return NULL;
183 }
184
185 temp_thresholds->warning = NULL;
186 temp_thresholds->critical = NULL;
187
188 if (string == NULL || strcmp(string, "") == 0)
189 return temp_thresholds;
190
191 if((temp_string = strdup(string)) == NULL) {
192 free(temp_thresholds);
193 utils_errno = NP_MEMORY_ERROR;
194 return NULL;
195 }
196
197 /* Find critical part and parse the range */
198 separator = index(temp_string, '/');
199 if (separator) {
200 *separator = '\0';
201 separator++;
202 }
203 if ((strcmp(temp_string, "") != 0) && (temp_range = _parse_range_string_v2( temp_string )) == NULL) {
204 free(temp_thresholds);
205 free(temp_string);
206 /* utils_errno already set */
207 return NULL;
208 }
209 temp_thresholds->critical = temp_range;
210
211 if (separator == NULL || strcmp(separator, "") == 0) {
212 return temp_thresholds;
213 }
214 /* UOM not processed yet */
215 if(( temp_range = _parse_range_string_v2( separator )) == NULL) {
216 free(temp_thresholds);
217 free(temp_string);
218 return NULL;
219 }
220 temp_thresholds->warning = temp_range;
221 return temp_thresholds;
222}
223
224thresholds
225*parse_thresholds_string(char *string)
226{
227 thresholds *my_threshold;
228 if ((my_threshold = _parse_thresholds_string(string)) == NULL)
229 _die_on_parse_error(utils_errno);
230 return my_threshold;
231}
232
101/* returns 0 if okay, otherwise 1 */ 233/* returns 0 if okay, otherwise 1 */
102int 234int
103_set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) 235_set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
@@ -139,8 +271,7 @@ set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_str
139 } 271 }
140} 272}
141 273
142void print_thresholds(const char *threshold_name, thresholds *my_threshold) { 274void print_thresholds(thresholds *my_threshold) {
143 printf("%s - ", threshold_name);
144 if (! my_threshold) { 275 if (! my_threshold) {
145 printf("Threshold not set"); 276 printf("Threshold not set");
146 } else { 277 } else {
diff --git a/lib/utils_base.h b/lib/utils_base.h
index bda76595..c616c5bd 100644
--- a/lib/utils_base.h
+++ b/lib/utils_base.h
@@ -31,7 +31,7 @@ typedef struct thresholds_struct {
31range *parse_range_string (char *); 31range *parse_range_string (char *);
32int _set_thresholds(thresholds **, char *, char *); 32int _set_thresholds(thresholds **, char *, char *);
33void set_thresholds(thresholds **, char *, char *); 33void set_thresholds(thresholds **, char *, char *);
34void print_thresholds(const char *, thresholds *); 34void print_thresholds(thresholds *);
35int check_range(double, range *); 35int check_range(double, range *);
36int get_status(double, thresholds *); 36int get_status(double, thresholds *);
37 37
@@ -39,9 +39,22 @@ char *np_escaped_string (const char *);
39 39
40void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3))); 40void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3)));
41 41
42/* Return codes for _set_thresholds */ 42
43#define NP_RANGE_UNPARSEABLE 1 43/* Parses a threshold string, as entered from command line */
44#define NP_WARN_WITHIN_CRIT 2 44/* Returns a malloc'd threshold* which can be freed */
45thresholds *parse_thresholds_string(char *);
46thresholds * _parse_thresholds_string(char *);
47void free_thresholds(thresholds *);
48range * _parse_range_string_v2(char *);
49int utils_errno;
50
51
52/* Error codes */
53#define NP_RANGE_UNPARSEABLE 1
54#define NP_WARN_WITHIN_CRIT 2
55#define NP_RANGE_MISSING_COLON 3
56#define NP_THRESHOLD_UNPARSEABLE 4
57#define NP_MEMORY_ERROR 5
45 58
46/* a simple check to see if we're running as root. 59/* a simple check to see if we're running as root.
47 * returns zero on failure, nonzero on success */ 60 * returns zero on failure, nonzero on success */
diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c
index c67573a3..32316410 100644
--- a/plugins/check_cluster.c
+++ b/plugins/check_cluster.c
@@ -80,7 +80,7 @@ int main(int argc, char **argv){
80 /* Initialize the thresholds */ 80 /* Initialize the thresholds */
81 set_thresholds(&thresholds, warn_threshold, crit_threshold); 81 set_thresholds(&thresholds, warn_threshold, crit_threshold);
82 if(verbose) 82 if(verbose)
83 print_thresholds("check_cluster", thresholds); 83 print_thresholds(thresholds);
84 84
85 /* check the data values */ 85 /* check the data values */
86 for(ptr=strtok(data_vals,",");ptr!=NULL;ptr=strtok(NULL,",")){ 86 for(ptr=strtok(data_vals,",");ptr!=NULL;ptr=strtok(NULL,",")){
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index d56d4571..7f3ca21d 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -44,6 +44,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
44#include "popen.h" 44#include "popen.h"
45#include "utils.h" 45#include "utils.h"
46#include "regex.h" 46#include "regex.h"
47#include "utils_base.h"
47 48
48#include <pwd.h> 49#include <pwd.h>
49 50
@@ -53,6 +54,7 @@ int check_thresholds (int);
53int convert_to_seconds (char *); 54int convert_to_seconds (char *);
54void print_help (void); 55void print_help (void);
55void print_usage (void); 56void print_usage (void);
57void actions_on_failed_state (int, char*); /* Helper routine */
56 58
57int wmax = -1; 59int wmax = -1;
58int cmax = -1; 60int cmax = -1;
@@ -74,13 +76,16 @@ int options = 0; /* bitmask of filter criteria to test against */
74/* Different metrics */ 76/* Different metrics */
75char *metric_name; 77char *metric_name;
76enum metric { 78enum metric {
79 NONE,
80 DEFAULT,
77 METRIC_PROCS, 81 METRIC_PROCS,
78 METRIC_VSZ, 82 METRIC_VSZ,
79 METRIC_RSS, 83 METRIC_RSS,
80 METRIC_CPU, 84 METRIC_CPU,
81 METRIC_ELAPSED 85 METRIC_ELAPSED
82}; 86};
83enum metric metric = METRIC_PROCS; 87enum metric metric = DEFAULT;
88enum metric default_metric = METRIC_PROCS;
84 89
85int verbose = 0; 90int verbose = 0;
86int uid; 91int uid;
@@ -99,6 +104,14 @@ char tmp[MAX_INPUT_BUFFER];
99 104
100FILE *ps_input = NULL; 105FILE *ps_input = NULL;
101 106
107thresholds *number_threshold = NULL;
108thresholds *vsz_threshold = NULL;
109thresholds *rss_threshold = NULL;
110thresholds *cpu_threshold = NULL;
111
112int warn = 0; /* number of processes in warn state */
113int crit = 0; /* number of processes in crit state */
114int result = STATE_UNKNOWN;
102 115
103int 116int
104main (int argc, char **argv) 117main (int argc, char **argv)
@@ -127,10 +140,14 @@ main (int argc, char **argv)
127 int pos; /* number of spaces before 'args' in `ps` output */ 140 int pos; /* number of spaces before 'args' in `ps` output */
128 int cols; /* number of columns in ps output */ 141 int cols; /* number of columns in ps output */
129 int expected_cols = PS_COLS - 1; 142 int expected_cols = PS_COLS - 1;
130 int warn = 0; /* number of processes in warn state */ 143 int i = 0; /* Temporary values */
131 int crit = 0; /* number of processes in crit state */ 144 double rss_sum = 0;
132 int i = 0; 145 double vsz_sum = 0;
133 int result = STATE_UNKNOWN; 146 double cpu_sum = 0;
147 double vsz_max = 0;
148 double rss_max = 0;
149 double cpu_max = 0;
150
134 151
135 setlocale (LC_ALL, ""); 152 setlocale (LC_ALL, "");
136 bindtextdomain (PACKAGE, LOCALEDIR); 153 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -141,7 +158,6 @@ main (int argc, char **argv)
141 procprog = malloc (MAX_INPUT_BUFFER); 158 procprog = malloc (MAX_INPUT_BUFFER);
142 159
143 asprintf (&metric_name, "PROCS"); 160 asprintf (&metric_name, "PROCS");
144 metric = METRIC_PROCS;
145 161
146 if (process_arguments (argc, argv) == ERROR) 162 if (process_arguments (argc, argv) == ERROR)
147 usage4 (_("Could not parse arguments")); 163 usage4 (_("Could not parse arguments"));
@@ -218,6 +234,7 @@ main (int argc, char **argv)
218 /* Ignore self */ 234 /* Ignore self */
219 if (mypid == procpid) continue; 235 if (mypid == procpid) continue;
220 236
237 /* Filter */
221 if ((options & STAT) && (strstr (statopts, procstat))) 238 if ((options & STAT) && (strstr (statopts, procstat)))
222 resultsum |= STAT; 239 resultsum |= STAT;
223 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) 240 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
@@ -244,35 +261,64 @@ main (int argc, char **argv)
244 continue; 261 continue;
245 262
246 procs++; 263 procs++;
247 if (verbose >= 2) { 264 if (verbose >= 3) {
248 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", 265 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
249 procuid, procvsz, procrss, 266 procuid, procvsz, procrss,
250 procpid, procppid, procpcpu, procstat, 267 procpid, procppid, procpcpu, procstat,
251 procetime, procprog, procargs); 268 procetime, procprog, procargs);
252 } 269 }
253 270
254 if (metric == METRIC_VSZ) 271 /* Check against metric - old style single check */
255 i = check_thresholds (procvsz); 272 if (metric == METRIC_VSZ) {
256 else if (metric == METRIC_RSS) 273 actions_on_failed_state( check_thresholds (procvsz), procprog );
257 i = check_thresholds (procrss); 274 } else if (metric == METRIC_RSS) {
275 actions_on_failed_state( check_thresholds (procrss), procprog );
258 /* TODO? float thresholds for --metric=CPU */ 276 /* TODO? float thresholds for --metric=CPU */
259 else if (metric == METRIC_CPU) 277 } else if (metric == METRIC_CPU) {
260 i = check_thresholds ((int)procpcpu); 278 actions_on_failed_state( check_thresholds ((int)procpcpu), procprog );
261 else if (metric == METRIC_ELAPSED) 279 } else if (metric == METRIC_ELAPSED) {
262 i = check_thresholds (procseconds); 280 actions_on_failed_state( check_thresholds (procseconds), procprog );
263 281 }
264 if (metric != METRIC_PROCS) { 282
265 if (i == STATE_WARNING) { 283 /* Check against all new style thresholds */
266 warn++; 284 if (vsz_threshold != NULL) {
267 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); 285 if ((i = get_status( procvsz, vsz_threshold )) != STATE_OK ) {
268 result = max_state (result, i); 286 actions_on_failed_state(i, procprog);
287 if (verbose >= 2) {
288 printf("VSZ state %d: proc=%s vsz=%d ", i, procprog, procvsz);
289 print_thresholds( vsz_threshold );
290 }
291 }
292 }
293 if (rss_threshold != NULL) {
294 if ((i = get_status( procrss, rss_threshold )) != STATE_OK ) {
295 actions_on_failed_state(i, procprog);
296 if (verbose >= 2) {
297 printf("RSS: proc=%s rss=%d ", procprog, procrss);
298 print_thresholds( rss_threshold );
299 }
269 } 300 }
270 if (i == STATE_CRITICAL) { 301 }
271 crit++; 302 if (cpu_threshold != NULL) {
272 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); 303 if (( i = get_status( procpcpu, cpu_threshold )) != STATE_OK ) {
273 result = max_state (result, i); 304 actions_on_failed_state(i, procprog);
305 if (verbose >= 2) {
306 printf("CPU: proc=%s cpu=%f ", procprog, procpcpu);
307 print_thresholds( cpu_threshold );
308 }
274 } 309 }
275 } 310 }
311
312 /* Summary information */
313 rss_sum += procrss;
314 vsz_sum += procvsz;
315 cpu_sum += procpcpu;
316 if (procrss > rss_max)
317 rss_max = procrss;
318 if (procvsz > vsz_max)
319 vsz_max = procvsz;
320 if (procpcpu > cpu_max)
321 cpu_max = procpcpu;
276 } 322 }
277 /* This should not happen */ 323 /* This should not happen */
278 else if (verbose) { 324 else if (verbose) {
@@ -308,7 +354,12 @@ main (int argc, char **argv)
308 354
309 /* Needed if procs found, but none match filter */ 355 /* Needed if procs found, but none match filter */
310 if ( metric == METRIC_PROCS ) { 356 if ( metric == METRIC_PROCS ) {
311 result = max_state (result, check_thresholds (procs) ); 357 result = max_state (result, i = check_thresholds (procs) );
358 }
359
360 if (number_threshold != NULL) {
361 i = get_status( procs, number_threshold );
362 actions_on_failed_state(i, "NUMBER_OF_PROCESSES");
312 } 363 }
313 364
314 if ( result == STATE_OK ) { 365 if ( result == STATE_OK ) {
@@ -316,12 +367,12 @@ main (int argc, char **argv)
316 } else if (result == STATE_WARNING) { 367 } else if (result == STATE_WARNING) {
317 printf ("%s %s: ", metric_name, _("WARNING")); 368 printf ("%s %s: ", metric_name, _("WARNING"));
318 if ( metric != METRIC_PROCS ) { 369 if ( metric != METRIC_PROCS ) {
319 printf (_("%d warn out of "), warn); 370 printf (_("Alerts: %d warn from "), warn);
320 } 371 }
321 } else if (result == STATE_CRITICAL) { 372 } else if (result == STATE_CRITICAL) {
322 printf ("%s %s: ", metric_name, _("CRITICAL")); 373 printf ("%s %s: ", metric_name, _("CRITICAL"));
323 if (metric != METRIC_PROCS) { 374 if (metric != METRIC_PROCS) {
324 printf (_("%d crit, %d warn out of "), crit, warn); 375 printf (_("Alerts: %d crit, %d warn from "), crit, warn);
325 } 376 }
326 } 377 }
327 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); 378 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs);
@@ -333,6 +384,17 @@ main (int argc, char **argv)
333 if ( verbose >= 1 && strcmp(fails,"") ) 384 if ( verbose >= 1 && strcmp(fails,"") )
334 printf (" [%s]", fails); 385 printf (" [%s]", fails);
335 386
387 printf(" | ");
388 if( number_threshold != NULL)
389 printf("number=%d ", procs);
390 if (procs > 0) {
391 if( vsz_threshold != NULL)
392 printf("vsz=%.0f ", vsz_sum/procs);
393 if( rss_threshold != NULL)
394 printf("rss=%.0f ", rss_sum/procs);
395 if( cpu_threshold != NULL)
396 printf("cpu=%.2f ", cpu_sum/procs);
397 }
336 printf ("\n"); 398 printf ("\n");
337 return result; 399 return result;
338} 400}
@@ -368,6 +430,22 @@ process_arguments (int argc, char **argv)
368 {"verbose", no_argument, 0, 'v'}, 430 {"verbose", no_argument, 0, 'v'},
369 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, 431 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
370 {"input-file", required_argument, 0, CHAR_MAX+2}, 432 {"input-file", required_argument, 0, CHAR_MAX+2},
433 {"number", optional_argument, 0, CHAR_MAX+3},
434 {"rss-threshold", optional_argument, 0, CHAR_MAX+4},
435 /*
436 {"rss-max", optional_argument, 0, CHAR_MAX+5},
437 {"rss-sum", optional_argument, 0, CHAR_MAX+6},
438 */
439 {"vsz-threshold", optional_argument, 0, CHAR_MAX+7},
440 /*
441 {"vsz-max", optional_argument, 0, CHAR_MAX+8},
442 {"vsz-sum", optional_argument, 0, CHAR_MAX+9},
443 */
444 {"cpu-threshold", optional_argument, 0, CHAR_MAX+10},
445 /*
446 {"cpu-max", optional_argument, 0, CHAR_MAX+11},
447 {"cpu-sum", optional_argument, 0, CHAR_MAX+12},
448 */
371 {0, 0, 0, 0} 449 {0, 0, 0, 0}
372 }; 450 };
373 451
@@ -537,6 +615,26 @@ process_arguments (int argc, char **argv)
537 case CHAR_MAX+2: 615 case CHAR_MAX+2:
538 input_filename = optarg; 616 input_filename = optarg;
539 break; 617 break;
618 case CHAR_MAX+3:
619 number_threshold = parse_thresholds_string(optarg);
620 if (metric == DEFAULT)
621 default_metric=NONE;
622 break;
623 case CHAR_MAX+4:
624 rss_threshold = parse_thresholds_string(optarg);
625 if (metric == DEFAULT)
626 default_metric=NONE;
627 break;
628 case CHAR_MAX+7:
629 vsz_threshold = parse_thresholds_string(optarg);
630 if (metric == DEFAULT)
631 default_metric=NONE;
632 break;
633 case CHAR_MAX+10:
634 cpu_threshold = parse_thresholds_string(optarg);
635 if (metric == DEFAULT)
636 default_metric=NONE;
637 break;
540 } 638 }
541 } 639 }
542 640
@@ -598,6 +696,9 @@ validate_arguments ()
598 if (fails==NULL) 696 if (fails==NULL)
599 fails = strdup(""); 697 fails = strdup("");
600 698
699 if (metric==DEFAULT)
700 metric = default_metric;
701
601 return options; 702 return options;
602} 703}
603 704
@@ -636,6 +737,21 @@ check_thresholds (int value)
636} 737}
637 738
638 739
740void
741actions_on_failed_state(int state, char *procprog) {
742 result = max_state (result, state);
743 if (state != STATE_WARNING && state != STATE_CRITICAL)
744 return;
745 if (state == STATE_WARNING) {
746 warn++;
747 }
748 if (state == STATE_CRITICAL) {
749 crit++;
750 }
751 /* TODO: This should be a hash, to remove duplicates */
752 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
753}
754
639/* convert the elapsed time to seconds */ 755/* convert the elapsed time to seconds */
640int 756int
641convert_to_seconds(char *etime) { 757convert_to_seconds(char *etime) {
@@ -707,31 +823,21 @@ print_help (void)
707 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); 823 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
708 printf (COPYRIGHT, copyright, email); 824 printf (COPYRIGHT, copyright, email);
709 825
710 printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); 826 print_usage ();
711 printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number"));
712 printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check."));
713 827
714 printf ("\n\n"); 828 printf ("\n\n");
715
716 print_usage ();
717 829
718 printf ("%s\n", _("Required Arguments:")); 830 printf("Checks all processes and, optionally, filters to a subset to check thresholds values against.\n");
719 printf (" %s\n", "-w, --warning=RANGE"); 831 printf("Can specify any of the following thresholds:\n");
720 printf (" %s\n", _("Generate warning state if metric is outside this range")); 832
721 printf (" %s\n", "-c, --critical=RANGE"); 833 printf(" --number=THRESHOLD - Compares the number of matching processes\n");
722 printf (" %s\n", _("Generate critical state if metric is outside this range")); 834 printf(" --vsz-threshold=THRESHOLD - Compares each process' vsz (in kilobytes)\n");
835 printf(" --rss-threshold=THRESHOLD - Compares each process' rss (in kilobytes)\n");
836 printf(" --cpu-threshold=THRESHOLD - Compares each process' cpu (in %%)\n");
837 /* TODO: Add support for etime */
838 printf("\n\n");
723 839
724 printf ("%s\n", _("Optional Arguments:")); 840 printf ("%s\n", _("Optional Arguments:"));
725 printf (" %s\n", "-m, --metric=TYPE");
726 printf (" %s\n", _("Check thresholds against metric. Valid types:"));
727 printf (" %s\n", _("PROCS - number of processes (default)"));
728 printf (" %s\n", _("VSZ - virtual memory size"));
729 printf (" %s\n", _("RSS - resident set memory size"));
730 printf (" %s\n", _("CPU - percentage cpu"));
731/* only linux etime is support currently */
732#if defined( __linux__ )
733 printf (" %s\n", _("ELAPSED - time elapsed in seconds"));
734#endif /* defined(__linux__) */
735 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); 841 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
736 842
737 printf (" %s\n", "-v, --verbose"); 843 printf (" %s\n", "-v, --verbose");
@@ -759,29 +865,25 @@ print_help (void)
759 printf (" %s\n", "-C, --command=COMMAND"); 865 printf (" %s\n", "-C, --command=COMMAND");
760 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); 866 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
761 867
762 printf(_("\n\ 868 printf("\n");
763RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
764specified 'max:min', a warning status will be generated if the\n\
765count is inside the specified range\n\n"));
766 869
767 printf(_("\ 870 printf("\
768This plugin checks the number of currently running processes and\n\ 871THRESHOLDS are specified as 'critical_range/warning_range' where\n\
769generates WARNING or CRITICAL states if the process count is outside\n\ 872RANGES are defined as 'min:max'. max can be removed if it is infinity.\n\
770the specified threshold ranges. The process count can be filtered by\n\ 873Alerts will occur inside this range, unless you specify '^' before\n\
771process owner, parent process PID, current state (e.g., 'Z'), or may\n\ 874the range, to mean alert outside this range\n\n");
772be the total number of running processes\n\n"));
773 875
774 printf ("%s\n", _("Examples:")); 876 printf ("%s\n", _("Examples:"));
775 printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); 877 printf (" %s\n", "check_procs --number=:2/5: -C portsentry");
776 printf (" %s\n", _("Warning if not two processes with command name portsentry.")); 878 printf (" %s\n", _("Warning if greater than five processes with command name portsentry."));
777 printf (" %s\n\n", _("Critical if < 2 or > 1024 processes")); 879 printf (" %s\n\n", _("Critical if <= 2 processes"));
778 printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); 880 printf (" %s\n", "check_procs --vsz-threshold=100:/50:");
779 printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing")); 881 printf (" %s\n\n", _("Warning if vsz of any processes is over 50K or critical if vsz is over 100K"));
780 printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); 882 printf (" %s\n", "check_procs --cpu-threshold=20:/10: --ereg-argument-array='java.*server'");
781 printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); 883 printf (" %s\n\n", _("For all processes with arguments matching the regular expression, warning if cpu is over 10% or critical if over 20%"));
782 printf (" %s\n\n", _("Alert if vsz of any processes over 50K or 100K")); 884 printf (" %s\n", "check_procs --rss-threshold=100: --number=/:10 --cpu-threshold=30:/10: -a '/usr/local/bin/perl' -u root");
783 printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); 885 printf (" %s\n", _("Critical if rss >= 100K, or warning if total number of process <= 10, or critical if cpu >= 30% or warning if cpu >= 10%."));
784 printf (" %s\n\n", _("Alert if cpu of any processes over 10%% or 20%%")); 886 printf (" %s\n", _("Filter by arguments containing '/usr/local/bin/perl' and owned by root"));
785 887
786 printf (_(UT_SUPPORT)); 888 printf (_(UT_SUPPORT));
787} 889}