X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fthreshold.c;h=8815a002efc260090ea9f96b8aadc2b8d5ce0148;hb=09147a2c9dde2e04e660409e7a5ac0eb09604b07;hp=922689d315abda618c5b8998ac72b9eb04b2f551;hpb=70160d8f57c9a767ae2ca14e31c8687ecbb10db3;p=collectd.git diff --git a/src/threshold.c b/src/threshold.c index 922689d3..8815a002 100644 --- a/src/threshold.c +++ b/src/threshold.c @@ -39,31 +39,6 @@ * The following functions add, delete, search, etc. configured thresholds to * the underlying AVL trees. */ -/* - * threshold_t *threshold_get - * - * Retrieve one specific threshold configuration. For looking up a threshold - * matching a value_list_t, see "threshold_search" below. Returns NULL if the - * specified threshold doesn't exist. - */ -static threshold_t *threshold_get (const char *hostname, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance) -{ /* {{{ */ - char name[6 * DATA_MAX_NAME_LEN]; - threshold_t *th = NULL; - - format_name (name, sizeof (name), - (hostname == NULL) ? "" : hostname, - (plugin == NULL) ? "" : plugin, plugin_instance, - (type == NULL) ? "" : type, type_instance); - name[sizeof (name) - 1] = '\0'; - - if (c_avl_get (threshold_tree, name, (void *) &th) == 0) - return (th); - else - return (NULL); -} /* }}} threshold_t *threshold_get */ /* * int ut_threshold_add @@ -139,58 +114,6 @@ static int ut_threshold_add (const threshold_t *th) } /* }}} int ut_threshold_add */ /* - * threshold_t *threshold_search - * - * Searches for a threshold configuration using all the possible variations of - * "Host", "Plugin" and "Type" blocks. Returns NULL if no threshold could be - * found. - * XXX: This is likely the least efficient function in collectd. - */ -static threshold_t *threshold_search (const value_list_t *vl) -{ /* {{{ */ - threshold_t *th; - - if ((th = threshold_get (vl->host, vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance)) != NULL) - return (th); - else if ((th = threshold_get (vl->host, vl->plugin, vl->plugin_instance, - vl->type, NULL)) != NULL) - return (th); - else if ((th = threshold_get (vl->host, vl->plugin, NULL, - vl->type, vl->type_instance)) != NULL) - return (th); - else if ((th = threshold_get (vl->host, vl->plugin, NULL, - vl->type, NULL)) != NULL) - return (th); - else if ((th = threshold_get (vl->host, "", NULL, - vl->type, vl->type_instance)) != NULL) - return (th); - else if ((th = threshold_get (vl->host, "", NULL, - vl->type, NULL)) != NULL) - return (th); - else if ((th = threshold_get ("", vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance)) != NULL) - return (th); - else if ((th = threshold_get ("", vl->plugin, vl->plugin_instance, - vl->type, NULL)) != NULL) - return (th); - else if ((th = threshold_get ("", vl->plugin, NULL, - vl->type, vl->type_instance)) != NULL) - return (th); - else if ((th = threshold_get ("", vl->plugin, NULL, - vl->type, NULL)) != NULL) - return (th); - else if ((th = threshold_get ("", "", NULL, - vl->type, vl->type_instance)) != NULL) - return (th); - else if ((th = threshold_get ("", "", NULL, - vl->type, NULL)) != NULL) - return (th); - - return (NULL); -} /* }}} threshold_t *threshold_search */ - -/* * Configuration * ============= * The following approximately two hundred functions are used to handle the @@ -596,7 +519,9 @@ static int ut_report_state (const data_set_t *ds, ": Value is no longer missing."); else status = ssnprintf (buf, bufsize, - ": All data sources are within range again."); + ": All data sources are within range again. " + "Current value of \"%s\" is %f.", + ds->ds[ds_index].name, values[ds_index]); buf += status; bufsize -= status; } @@ -714,23 +639,40 @@ static int ut_check_one_data_source (const data_set_t *ds, /* XXX: This is an experimental code, not optimized, not fast, not reliable, * and probably, do not work as you expect. Enjoy! :D */ - if ( (th->hysteresis > 0) && ((prev_state = uc_get_state(ds,vl)) != STATE_OKAY) ) - { - switch(prev_state) + if (th->hysteresis > 0) + { + prev_state = uc_get_state(ds,vl); + /* The purpose of hysteresis is elliminating flapping state when the value + * oscilates around the thresholds. In other words, what is important is + * the previous state; if the new value would trigger a transition, make + * sure that we artificially widen the range which is considered to apply + * for the previous state, and only trigger the notification if the value + * is outside of this expanded range. + * + * There is no hysteresis for the OKAY state. + * */ + gauge_t hysteresis_for_warning = 0, hysteresis_for_failure = 0; + switch (prev_state) { case STATE_ERROR: - if ( (!isnan (th->failure_min) && ((th->failure_min + th->hysteresis) < values[ds_index])) || - (!isnan (th->failure_max) && ((th->failure_max - th->hysteresis) > values[ds_index])) ) - return (STATE_OKAY); - else - is_failure++; + hysteresis_for_failure = th->hysteresis; + break; case STATE_WARNING: - if ( (!isnan (th->warning_min) && ((th->warning_min + th->hysteresis) < values[ds_index])) || - (!isnan (th->warning_max) && ((th->warning_max - th->hysteresis) > values[ds_index])) ) - return (STATE_OKAY); - else - is_warning++; - } + hysteresis_for_warning = th->hysteresis; + break; + case STATE_OKAY: + /* do nothing -- the hysteresis only applies to the non-normal states */ + break; + } + + if ((!isnan (th->failure_min) && (th->failure_min + hysteresis_for_failure > values[ds_index])) + || (!isnan (th->failure_max) && (th->failure_max - hysteresis_for_failure < values[ds_index]))) + is_failure++; + + if ((!isnan (th->warning_min) && (th->warning_min + hysteresis_for_warning > values[ds_index])) + || (!isnan (th->warning_max) && (th->warning_max - hysteresis_for_warning < values[ds_index]))) + is_warning++; + } else { /* no hysteresis */ if ((!isnan (th->failure_min) && (th->failure_min > values[ds_index])) @@ -740,7 +682,7 @@ static int ut_check_one_data_source (const data_set_t *ds, if ((!isnan (th->warning_min) && (th->warning_min > values[ds_index])) || (!isnan (th->warning_max) && (th->warning_max < values[ds_index]))) is_warning++; - } + } if (is_failure != 0) return (STATE_ERROR); @@ -909,6 +851,7 @@ static int ut_missing (const value_list_t *vl, cdtime_t missing_time; char identifier[6 * DATA_MAX_NAME_LEN]; notification_t n; + cdtime_t now; if (threshold_tree == NULL) return (0); @@ -918,13 +861,15 @@ static int ut_missing (const value_list_t *vl, if ((th == NULL) || ((th->flags & UT_FLAG_INTERESTING) == 0)) return (0); - missing_time = cdtime () - vl->time; + now = cdtime (); + missing_time = now - vl->time; FORMAT_VL (identifier, sizeof (identifier), vl); NOTIFICATION_INIT_VL (&n, vl); ssnprintf (n.message, sizeof (n.message), "%s has not been updated for %.3f seconds.", identifier, CDTIME_T_TO_DOUBLE (missing_time)); + n.time = now; plugin_dispatch_notification (&n);