From da933ca8f0bd3d3ec9ee5681f0e88f3b46e884d3 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Wed, 23 Jan 2008 18:14:27 +0100 Subject: [PATCH] src/utils_threshold.c: Implemented `warning' and `failure' thresholds. The options `Min' and `Max' have been renamed to `FailureMin', `FailureMax', `WarningMin', and `WarningMax'. --- src/collectd.conf.pod | 32 ++++++++++----- src/utils_threshold.c | 94 ++++++++++++++++++++++++++++--------------- 2 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 20c84b51..92a5e254 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -1082,8 +1082,10 @@ information. - Min 0.00 - Max 1000.00 + WarningMin 0.00 + WarningMax 1000.00 + FailureMin 0.00 + FailureMax 1200.00 Invert false Instance "bar" @@ -1091,20 +1093,20 @@ information. Instance "eth0" - Max 10000000 + FailureMax 10000000 Instance "idle" - Min 10 + FailureMin 10 Instance "cached" - Min 100000000 + WarningMin 100000000 @@ -1124,21 +1126,29 @@ included in a C block. Currently the following statements are recognized: =over 4 -=item B I +=item B I + +=item B I Sets the upper bound of acceptable values. If unset defaults to positive -infinity. +infinity. If a value is greater than B a B notification +will be created. If the value is greater than B but less than (or +equal to) B a B notification will be created. + +=item B I -=item B I +=item B I Sets the lower bound of acceptable values. If unset defaults to negative -infinity. +infinity. If a value is less than B a B notification will +be created. If the value is less than B but greater than (or equal +to) B a B notification will be created. =item B B|B If set to B the range of acceptable values is inverted, i.Ee. -values between B and B are not okay. Defaults, of course, to -B. +values between B and B (B and +B) are not okay. Defaults to B. =item B B|B diff --git a/src/utils_threshold.c b/src/utils_threshold.c index 15ccf9c3..32408876 100644 --- a/src/utils_threshold.c +++ b/src/utils_threshold.c @@ -41,8 +41,10 @@ typedef struct threshold_s char plugin_instance[DATA_MAX_NAME_LEN]; char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; - gauge_t min; - gauge_t max; + gauge_t warning_min; + gauge_t warning_max; + gauge_t failure_min; + gauge_t failure_max; int flags; } threshold_t; /* }}} */ @@ -138,12 +140,15 @@ static int ut_config_type_max (threshold_t *th, oconfig_item_t *ci) if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { - WARNING ("threshold values: The `Max' option needs exactly one " - "number argument."); + WARNING ("threshold values: The `%s' option needs exactly one " + "number argument.", ci->key); return (-1); } - th->max = ci->values[0].value.number; + if (strcasecmp (ci->key, "WarningMax") == 0) + th->warning_min = ci->values[0].value.number; + else + th->failure_min = ci->values[0].value.number; return (0); } /* int ut_config_type_max */ @@ -153,12 +158,15 @@ static int ut_config_type_min (threshold_t *th, oconfig_item_t *ci) if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { - WARNING ("threshold values: The `Min' option needs exactly one " - "number argument."); + WARNING ("threshold values: The `%s' option needs exactly one " + "number argument.", ci->key); return (-1); } - th->min = ci->values[0].value.number; + if (strcasecmp (ci->key, "WarningMin") == 0) + th->warning_min = ci->values[0].value.number; + else + th->failure_min = ci->values[0].value.number; return (0); } /* int ut_config_type_min */ @@ -223,8 +231,10 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci) strncpy (th.type, ci->values[0].value.string, sizeof (th.type)); th.type[sizeof (th.type) - 1] = '\0'; - th.min = NAN; - th.max = NAN; + th.warning_min = NAN; + th.warning_max = NAN; + th.failure_min = NAN; + th.failure_max = NAN; for (i = 0; i < ci->children_num; i++) { @@ -233,9 +243,11 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci) if (strcasecmp ("Instance", option->key) == 0) status = ut_config_type_instance (&th, option); - else if (strcasecmp ("Max", option->key) == 0) + else if ((strcasecmp ("WarningMax", option->key) == 0) + || (strcasecmp ("FailureMax", option->key) == 0)) status = ut_config_type_max (&th, option); - else if (strcasecmp ("Min", option->key) == 0) + else if ((strcasecmp ("WarningMin", option->key) == 0) + || (strcasecmp ("FailureMin", option->key) == 0)) status = ut_config_type_min (&th, option); else if (strcasecmp ("Invert", option->key) == 0) status = ut_config_type_invert (&th, option); @@ -398,8 +410,10 @@ int ut_config (const oconfig_item_t *ci) } memset (&th, '\0', sizeof (th)); - th.min = NAN; - th.max = NAN; + th.warning_min = NAN; + th.warning_max = NAN; + th.failure_min = NAN; + th.failure_max = NAN; for (i = 0; i < ci->children_num; i++) { @@ -501,6 +515,8 @@ int ut_check_threshold (const data_set_t *ds, const value_list_t *vl) if (threshold_tree == NULL) return (0); + /* Is this lock really necessary? So far, thresholds are only inserted at + * startup. -octo */ pthread_mutex_lock (&threshold_lock); th = threshold_search (ds, vl); pthread_mutex_unlock (&threshold_lock); @@ -515,31 +531,40 @@ int ut_check_threshold (const data_set_t *ds, const value_list_t *vl) for (i = 0; i < ds->ds_num; i++) { - int out_of_range = 0; int is_inverted = 0; + int is_warning = 0; + int is_failure = 0; if ((th->flags & UT_FLAG_INVERT) != 0) is_inverted = 1; - if ((!isnan (th->min) && (th->min > values[i])) - || (!isnan (th->max) && (th->max < values[i]))) - out_of_range = 1; - - /* If only one of these conditions is true, there is a problem */ - if ((out_of_range + is_inverted) == 1) + if ((!isnan (th->failure_min) && (th->failure_min > values[i])) + || (!isnan (th->failure_max) && (th->failure_max < values[i]))) + is_failure = is_inverted - 1; + if ((!isnan (th->warning_min) && (th->warning_min > values[i])) + || (!isnan (th->warning_max) && (th->warning_max < values[i]))) + is_warning = is_inverted - 1; + + if ((is_failure != 0) || (is_warning != 0)) { notification_t n; char *buf; size_t bufsize; int status; - WARNING ("ut_check_threshold: ds[%s]: %lf <= !%lf <= %lf (invert: %s)", - ds->ds[i].name, th->min, values[i], th->max, + double min; + double max; + + min = (is_failure != 0) ? th->failure_min : th->warning_min; + max = (is_failure != 0) ? th->failure_max : th->warning_max; + + DEBUG ("ut_check_threshold: ds[%s]: %lf <= !%lf <= %lf (invert: %s)", + ds->ds[i].name, min, values[i], max, is_inverted ? "true" : "false"); /* Copy the associative members */ NOTIFICATION_INIT_VL (&n, vl, ds); - n.severity = NOTIF_FAILURE; + n.severity = (is_failure != 0) ? NOTIF_FAILURE : NOTIF_WARNING; n.time = vl->time; buf = n.message; @@ -572,29 +597,32 @@ int ut_check_threshold (const data_set_t *ds, const value_list_t *vl) if (is_inverted) { - if (!isnan (th->min) && !isnan (th->max)) + if (!isnan (min) && !isnan (max)) { status = snprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%lf. That is within the critical region of %lf and %lf.", + "%f. That is within the %s region of %f and %f.", ds->ds[i].name, values[i], - th->min, th->min); + (is_failure != 0) ? "failure" : "warning", + min, min); } else { status = snprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%lf. That is %s the configured threshold of %lf.", + "%f. That is %s the %s threshold of %f.", ds->ds[i].name, values[i], - isnan (th->min) ? "below" : "above", - isnan (th->min) ? th->max : th->min); + isnan (min) ? "below" : "above", + (is_failure != 0) ? "failure" : "warning", + isnan (min) ? max : min); } } else /* (!is_inverted) */ { status = snprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%lf. That is %s the configured threshold of %lf.", + "%f. That is %s the %s threshold of %f.", ds->ds[i].name, values[i], - (values[i] < th->min) ? "below" : "above", - (values[i] < th->min) ? th->min : th->max); + (values[i] < min) ? "below" : "above", + (is_failure != 0) ? "failure" : "warning", + (values[i] < min) ? min : max); } buf += status; bufsize -= status; -- 2.30.2