8 #include <sys/socket.h>
12 * This weird macro cascade forces the glibc to define `NAN'. I don't know
13 * another way to solve this, so more intelligent solutions are welcome. -octo
16 # define DISABLE__USE_ISOC99 1
17 # define __USE_ISOC99 1
20 #ifdef DISABLE__USE_ISOC99
21 # undef DISABLE__USE_ISOC99
27 #define RET_CRITICAL 2
40 typedef struct range_s range_t;
43 extern int optind, opterr, optopt;
45 static char *socket_file_g = NULL;
46 static char *value_string_g = NULL;
47 static range_t range_critical_g;
48 static range_t range_warning_g;
49 static int consolitation_g = CON_NONE;
51 static void parse_range (char *string, range_t *range)
62 max_ptr = strchr (string, ':');
75 assert (max_ptr != NULL);
80 /* :10 == ~:10 == -inf:10 */
81 else if ((*min_ptr == '\0') || (*min_ptr == '~'))
84 range->min = atof (min_ptr);
86 if ((*max_ptr == '\0') || (*max_ptr == '~'))
89 range->max = atof (max_ptr);
90 } /* void parse_range */
92 int match_range (range_t *range, double value)
96 if ((range->min != NAN) && (range->min > value))
98 if ((range->max != NAN) && (range->max < value))
101 return (((ret - range->invert) == 0) ? 0 : 1);
104 static int get_values (int *ret_values_num, double **ret_values,
105 char ***ret_values_names)
107 struct sockaddr_un sa;
119 fd = socket (PF_UNIX, SOCK_STREAM, 0);
122 fprintf (stderr, "socket failed: %s\n",
127 memset (&sa, '\0', sizeof (sa));
128 sa.sun_family = AF_UNIX;
129 strncpy (sa.sun_path, socket_file_g,
130 sizeof (sa.sun_path) - 1);
132 status = connect (fd, (struct sockaddr *) &sa, sizeof (sa));
135 fprintf (stderr, "connect failed: %s\n",
140 fh = fdopen (fd, "r+");
143 fprintf (stderr, "fdopen failed: %s\n",
149 fprintf (fh, "GETVAL %s\n", value_string_g);
152 if (fgets (buffer, sizeof (buffer), fh) == NULL)
154 fprintf (stderr, "fgets failed: %s\n",
161 values_num = atoi (buffer);
165 values = (double *) malloc (values_num * sizeof (double));
168 fprintf (stderr, "malloc failed: %s\n",
173 values_names = (char **) malloc (values_num * sizeof (char *));
174 if (values_names == NULL)
176 fprintf (stderr, "malloc failed: %s\n",
183 char *ptr = strchr (buffer, ' ') + 1;
188 while ((key = strtok (ptr, " \t")) != NULL)
191 value = strchr (key, '=');
194 *value = '\0'; value++;
196 values_names[i] = strdup (key);
197 values[i] = atof (value);
206 *ret_values_num = values_num;
207 *ret_values = values;
208 *ret_values_names = values_names;
211 } /* int get_values */
213 static void usage (const char *name)
215 fprintf (stderr, "Usage: %s <-s socket> <-n value_spec> [options]\n"
217 "Valid options are:\n"
218 " -s <socket> Path to collectd's UNIX-socket\n"
219 " -n <v_spec> Value specification to get from collectd\n"
220 " -c <range> Critical range\n"
221 " -w <range> Range for critical values\n",
226 int do_check_con_none (int values_num, double *values, char **values_names)
230 int num_critical = 0;
234 for (i = 0; i < values_num; i++)
236 if (values[i] == NAN)
238 else if (match_range (&range_critical_g, values[i]) != 0)
240 else if (match_range (&range_warning_g, values[i]) != 0)
246 if ((num_critical != 0) || (values_num == 0))
248 printf ("CRITICAL: %i critical, %i warning, %i okay\n",
249 num_critical, num_warning, num_okay);
250 return (RET_CRITICAL);
252 else if (num_warning != 0)
254 printf ("WARNING: %i warning, %i okay\n",
255 num_warning, num_okay);
256 return (RET_WARNING);
260 printf ("OKAY: %i okay\n", num_okay);
264 return (RET_UNKNOWN);
265 } /* int do_check_con_none */
267 int do_check_con_average (int values_num, double *values, char **values_names)
275 for (i = 0; i < values_num; i++)
277 if (values[i] != NAN)
286 printf ("WARNING: No defined values found\n");
287 return (RET_WARNING);
290 if (match_range (&range_critical_g, total / total_num) != 0)
292 printf ("CRITICAL: Average = %lf\n",
293 (double) (total / total_num));
294 return (RET_CRITICAL);
296 else if (match_range (&range_warning_g, total / total_num) != 0)
298 printf ("WARNING: Average = %lf\n",
299 (double) (total / total_num));
300 return (RET_WARNING);
304 printf ("OKAY: Average = %lf\n",
305 (double) (total / total_num));
309 return (RET_UNKNOWN);
310 } /* int do_check_con_average */
312 int do_check_con_sum (int values_num, double *values, char **values_names)
320 for (i = 0; i < values_num; i++)
322 if (values[i] != NAN)
331 printf ("WARNING: No defined values found\n");
332 return (RET_WARNING);
335 if (match_range (&range_critical_g, total) != 0)
337 printf ("CRITICAL: Sum = %lf\n", total);
338 return (RET_CRITICAL);
340 else if (match_range (&range_warning_g, total) != 0)
342 printf ("WARNING: Sum = %lf\n", total);
343 return (RET_WARNING);
347 printf ("OKAY: Sum = %lf\n", total);
351 return (RET_UNKNOWN);
352 } /* int do_check_con_sum */
361 if (get_values (&values_num, &values, &values_names) != 0)
363 fputs ("ERROR: Cannot get values from daemon\n", stdout);
364 return (RET_CRITICAL);
367 for (i = 0; i < values_num; i++)
368 printf ("%s=%lf\n", values_names[i], values[i]);
370 if (consolitation_g == CON_NONE)
371 return (do_check_con_none (values_num, values, values_names));
372 else if (consolitation_g == CON_AVERAGE)
373 return (do_check_con_average (values_num, values, values_names));
374 else if (consolitation_g == CON_SUM)
375 return (do_check_con_sum (values_num, values, values_names));
377 return (RET_UNKNOWN);
380 int main (int argc, char **argv)
382 range_critical_g.min = NAN;
383 range_critical_g.max = NAN;
384 range_critical_g.invert = 0;
386 range_warning_g.min = NAN;
387 range_warning_g.max = NAN;
388 range_warning_g.invert = 0;
394 c = getopt (argc, argv, "w:c:s:n:g:h");
401 parse_range (optarg, &range_critical_g);
404 parse_range (optarg, &range_warning_g);
407 socket_file_g = optarg;
410 value_string_g = optarg;
413 if (strcasecmp (optarg, "none") == 0)
414 consolitation_g = CON_NONE;
415 else if (strcasecmp (optarg, "average") == 0)
416 consolitation_g = CON_AVERAGE;
417 else if (strcasecmp (optarg, "sum") == 0)
418 consolitation_g = CON_SUM;
427 if ((socket_file_g == NULL) || (value_string_g == NULL))
430 return (do_check ());