[collectd] [patch] collectd-nagios human readable input and output
daniel hilst
danielhilst at gmail.com
Tue Aug 14 22:42:30 CEST 2012
collectd-nagios outputs values in absolute form, as in
# ./collectd-nagios -s ../var/run/collectd-unixsock -H $myhost -n
df-root/df_complex-used
OKAY: 0 critical, 0 warning, 1 okay | value=30707630000.000000;;;;
I've create a patch to improve its outputs, to it prints only the
current status and the value on human readable, like this:
# ./collectd-nagios -s ../var/run/collectd-unixsock -H $myhost -n
df-root/df_complex-used -R
OK: 28.60 GB,
Take attetion on -R option, is new.. You can force collectd-nagios to
print on some ratio, in megabytes for example:
# ./collectd-nagios -s ../var/run/collectd-unixsock -H $myhost -n
df-root/df_complex-used -rm
OK: 29287.20 MB,
And you can pass suffixes to -w and -c options.. so:
# ./collectd-nagios -s ../var/run/collectd-unixsock -H $myhost -n
df-root/df_complex-used -R -c @0:30g
CRITICAL: 28.60 GB,
# ./collectd-nagios -s ../var/run/collectd-unixsock -H $myhost -n
df-root/df_complex-used -R -c @0:2500m
OK: 28.60 GB,
The suffixes supported are k, m and g, and they are case insensitivy
Yet... there is a bug.. -c and -w options expect a range.. so n:m.. if
you do not pass a range to, it segfaults.. I'm working on this.. just
need some free time to do it..
As workaround I use -c n:n instead of -c n
I hope you like, cheers!
Hilst,
-------------- next part --------------
>From f1dd868beebb4ef89e6bab619c6ea8647d57a13d Mon Sep 17 00:00:00 2001
From: Daniel Hilst <danielhilst at gmail.com>
Date: Mon, 6 Feb 2012 11:18:28 -0200
Subject: [PATCH] collectd-nagios: added support to k/m/g prefix on -w and -c
options. Added two new options -R and -r <rate>
---
src/collectd-nagios.c | 192 ++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 167 insertions(+), 25 deletions(-)
diff --git a/src/collectd-nagios.c b/src/collectd-nagios.c
index 88a5302..795e9f8 100644
--- a/src/collectd-nagios.c
+++ b/src/collectd-nagios.c
@@ -27,6 +27,7 @@
# define __attribute__(x) /**/
#endif
+#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
@@ -78,6 +79,7 @@
#define CON_SUM 2
#define CON_PERCENTAGE 3
+
struct range_s
{
double min;
@@ -86,6 +88,33 @@ struct range_s
};
typedef struct range_s range_t;
+struct rate_v {
+ char *name;
+ double value;
+};
+
+static struct rate_v rates[] = {
+ { "", 1 },
+ { " KB", 0x400 },
+ { " MB", 0x100000 },
+ { " GB", 0x40000000 },
+/* collectd-nagios.c:101: warning: integer constant is too large for 'long' type */
+/* { " TB", 0x10000000000 }, */
+ { NULL, 0 },
+};
+
+enum {
+ BT_INDX,
+ KB_INDX,
+ MB_INDX,
+ GB_INDX,
+ TB_INDX,
+};
+
+static struct rate_v *rate_ptr = &rates[BT_INDX];
+/* static int rate = 1; */
+/* static char *ratestr = ""; */
+
extern char *optarg;
extern int optind, opterr, optopt;
@@ -101,6 +130,7 @@ static _Bool nan_is_error_g = 0;
static char **match_ds_g = NULL;
static int match_ds_num_g = 0;
+
/* `strdup' is an XSI extension. I don't want to pull in all of XSI just for
* that, so here's an own implementation.. It's easy enough. The GCC attributes
* are supposed to get good performance.. -octo */
@@ -117,6 +147,16 @@ static char *cn_strdup (const char *str) /* {{{ */
return (ret);
} /* }}} char *cn_strdup */
+struct rate_v *convert_rate(double n)
+{
+ struct rate_v *ptr;
+
+ for (ptr = rates; n > 1024 && ptr->name; ptr++, n /= 1024)
+ ; /* empty */
+
+ return ptr;
+}
+
static int filter_ds (size_t *values_num,
double **values, char ***values_names)
{
@@ -191,6 +231,10 @@ static void parse_range (char *string, range_t *range)
{
char *min_ptr;
char *max_ptr;
+ int min_ptr_len;
+ int max_ptr_len;
+ long min_rate = 1;
+ long max_rate = 1;
if (*string == '@')
{
@@ -210,9 +254,51 @@ static void parse_range (char *string, range_t *range)
*max_ptr = '\0';
max_ptr++;
}
-
+
assert (max_ptr != NULL);
+ min_ptr_len = strlen(min_ptr) - 1;
+ max_ptr_len = strlen(max_ptr) - 1;
+
+ if (isalpha(min_ptr[min_ptr_len])) {
+ switch (tolower(min_ptr[min_ptr_len])) {
+ /* case 't': */
+ /* min_rate = rates[TB_INDX].value; */
+ /* break; */
+ case 'g':
+ min_rate = rates[GB_INDX].value;
+ break;
+ case 'm':
+ min_rate = rates[MB_INDX].value;
+ break;
+ case 'k':
+ min_rate = rates[KB_INDX].value;
+ break;
+ }
+
+ min_ptr[min_ptr_len] = '\0';
+ }
+
+ if (isalpha(max_ptr[max_ptr_len])) {
+ switch (tolower(max_ptr[max_ptr_len])) {
+ /* case 't': */
+ /* max_rate = rates[TB_INDX].value; */
+ /* break; */
+ case 'g':
+ max_rate = rates[GB_INDX].value;
+ break;
+ case 'm':
+ max_rate = rates[MB_INDX].value;
+ break;
+ case 'k':
+ max_rate = rates[KB_INDX].value;
+ break;
+ }
+
+ max_ptr[max_ptr_len] = '\0';
+ }
+
+
/* `10' == `0:10' */
if (min_ptr == NULL)
range->min = 0.0;
@@ -220,12 +306,12 @@ static void parse_range (char *string, range_t *range)
else if ((*min_ptr == '\0') || (*min_ptr == '~'))
range->min = NAN;
else
- range->min = atof (min_ptr);
+ range->min = atof (min_ptr) * min_rate;
if ((*max_ptr == '\0') || (*max_ptr == '~'))
range->max = NAN;
else
- range->max = atof (max_ptr);
+ range->max = atof (max_ptr) * max_rate;
} /* void parse_range */
static int match_range (range_t *range, double value)
@@ -253,9 +339,11 @@ static void usage (const char *name)
" -g <consol> Method to use to consolidate several DSes.\n"
" See below for a list of valid arguments.\n"
" -H <host> Hostname to query the values for.\n"
- " -c <range> Critical range\n"
- " -w <range> Warning range\n"
+ " -c <range> Critical range. Accept k/m/g suffixes\n"
+ " -w <range> Warning range. Accept k/m/g suffixes\n"
" -m Treat \"Not a Number\" (NaN) as critical (default: warning)\n"
+ " -r <rate> Print output in rate, m for megabytes, g for gigabytes, k for kilobytes\n"
+ " -R Print output in human readable format (k/m/g)\n"
"\n"
"Consolidation functions:\n"
" none: Apply the warning- and critical-ranges to each data-source\n"
@@ -364,7 +452,7 @@ static int do_check_con_none (size_t values_num,
}
else if ((num_critical == 0) && (num_warning == 0))
{
- status_str = "OKAY";
+ status_str = "OK";
status_code = RET_OKAY;
}
else if (num_critical == 0)
@@ -378,13 +466,17 @@ static int do_check_con_none (size_t values_num,
status_code = RET_CRITICAL;
}
- printf ("%s: %i critical, %i warning, %i okay", status_str,
- num_critical, num_warning, num_okay);
+ printf ("%s: ", status_str);
if (values_num > 0)
{
- printf (" |");
- for (i = 0; i < values_num; i++)
- printf (" %s=%f;;;;", values_names[i], values[i]);
+ for (i = 0; i < values_num; i++) {
+ if (!rate_ptr) { /* -R option */
+ struct rate_v *ptr = convert_rate(values[i]);
+ printf ("%.2f%s, ", values[i] / ptr->value, ptr->name);
+ } else { /* -r option */
+ printf ("%.2f%s, ", values[i] / rate_ptr->value, rate_ptr->name);
+ }
+ }
}
printf ("\n");
@@ -439,13 +531,25 @@ static int do_check_con_average (size_t values_num,
}
else
{
- status_str = "OKAY";
+ status_str = "OK";
status_code = RET_OKAY;
}
- printf ("%s: %g average |", status_str, average);
- for (i = 0; i < values_num; i++)
- printf (" %s=%f;;;;", values_names[i], values[i]);
+ if (!rate_ptr) {
+ struct rate_v *ptr = convert_rate(average);
+ printf ("%s: %.2g %s average ", status_str, average / ptr->value, ptr->name);
+ } else {
+ printf ("%s: %.2g %s average ", status_str, average / rate_ptr->value, rate_ptr->name);
+ }
+
+ for (i = 0; i < values_num; i++) {
+ if (!rate_ptr) {
+ struct rate_v *ptr = convert_rate(values[i]);
+ printf ("%.2f%s, ", values[i] / ptr->value, ptr->name);
+ } else {
+ printf ("%.2f%s, ", values[i] / rate_ptr->value, rate_ptr->name);
+ }
+ }
printf ("\n");
return (status_code);
@@ -496,13 +600,25 @@ static int do_check_con_sum (size_t values_num,
}
else
{
- status_str = "OKAY";
+ status_str = "OK";
status_code = RET_OKAY;
}
- printf ("%s: %g sum |", status_str, total);
- for (i = 0; i < values_num; i++)
- printf (" %s=%f;;;;", values_names[i], values[i]);
+ if (!rate_ptr) {
+ struct rate_v *ptr = convert_rate(total);
+ printf ("%s: %.2g %s sum ", status_str, total / ptr->value, ptr->name);
+ } else {
+ printf ("%s: %.2g %s sum ", status_str, total / rate_ptr->value, rate_ptr->name);
+ }
+
+ for (i = 0; i < values_num; i++) {
+ if (!rate_ptr) {
+ struct rate_v *ptr = convert_rate(values[i]);
+ printf ("%.2f%s, ", values[i] / ptr->value, ptr->name);
+ } else {
+ printf ("%.2f%s, ", values[i] / rate_ptr->value, rate_ptr->name);
+ }
+ }
printf ("\n");
return (status_code);
@@ -559,13 +675,20 @@ static int do_check_con_percentage (size_t values_num,
}
else
{
- status_str = "OKAY";
+ status_str = "OK";
status_code = RET_OKAY;
}
- printf ("%s: %lf percent |", status_str, percentage);
- for (i = 0; i < values_num; i++)
- printf (" %s=%lf;;;;", values_names[i], values[i]);
+ printf ("%s: %.2lf percent ", status_str, percentage);
+ for (i = 0; i < values_num; i++) {
+ if (!rate_ptr) {
+ struct rate_v *ptr = convert_rate(values[i]);
+ printf ("%.2lf%s, ", values[i] / ptr->value, ptr->name);
+ } else {
+ printf ("%.2lf%s, ", values[i] / rate_ptr->value, rate_ptr->name);
+ }
+ }
+ printf("\n");
return (status_code);
} /* int do_check_con_percentage */
@@ -647,7 +770,7 @@ int main (int argc, char **argv)
{
int c;
- c = getopt (argc, argv, "w:c:s:n:H:g:d:hm");
+ c = getopt (argc, argv, "w:c:s:n:H:g:d:hmr:R");
if (c < 0)
break;
@@ -710,7 +833,26 @@ int main (int argc, char **argv)
case 'm':
nan_is_error_g = 1;
break;
- default:
+ case 'r':
+ switch (tolower(*optarg)) {
+ /* case 't': */
+ /* rate_ptr = &rates[TB_INDX]; */
+ /* break; */
+ case 'g':
+ rate_ptr = &rates[GB_INDX];
+ break;
+ case 'm':
+ rate_ptr = &rates[MB_INDX];
+ break;
+ case 'k':
+ rate_ptr = &rates[KB_INDX];
+ break;
+ }
+ break;
+ case 'R':
+ rate_ptr = NULL;
+ break;
+ default:
usage (argv[0]);
} /* switch (c) */
}
--
1.7.8.4
More information about the collectd
mailing list