From: Luis Fernández Álvarez Date: Wed, 24 Oct 2018 13:49:35 +0000 (+0200) Subject: Add a new UNKNOWN state as the initial state of metrics X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=900a07ed70cdcfe3022d3dc25d275fe2015f4fdc;p=collectd.git Add a new UNKNOWN state as the initial state of metrics * UNKNOWN becomes the default state of the metrics. * States are renumbered so UNKNOWN is lower than OKAY and the threshold evaluation logic is consistent. * If an invalid datasource is set in a threshold it will resolve to UNKNOWN. --- diff --git a/src/daemon/utils_cache.c b/src/daemon/utils_cache.c index 610c11e5..e09b0999 100644 --- a/src/daemon/utils_cache.c +++ b/src/daemon/utils_cache.c @@ -201,7 +201,7 @@ static int uc_insert(const data_set_t *ds, const value_list_t *vl, ce->last_time = vl->time; ce->last_update = cdtime(); ce->interval = vl->interval; - ce->state = STATE_OKAY; + ce->state = STATE_UNKNOWN; if (c_avl_insert(cache_tree, key_copy, ce) != 0) { sfree(key_copy); diff --git a/src/daemon/utils_cache.h b/src/daemon/utils_cache.h index 7200906d..d3ea9362 100644 --- a/src/daemon/utils_cache.h +++ b/src/daemon/utils_cache.h @@ -31,9 +31,10 @@ #include "plugin.h" -#define STATE_OKAY 0 -#define STATE_WARNING 1 -#define STATE_ERROR 2 +#define STATE_UNKNOWN 0 +#define STATE_OKAY 1 +#define STATE_WARNING 2 +#define STATE_ERROR 3 #define STATE_MISSING 15 int uc_init(void); diff --git a/src/threshold.c b/src/threshold.c index 79300f14..9d343630 100644 --- a/src/threshold.c +++ b/src/threshold.c @@ -309,7 +309,10 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl, /* If the state didn't change, report if `persistent' is specified. If the * state is `okay', then only report if `persist_ok` flag is set. */ if (state == state_old) { - if ((th->flags & UT_FLAG_PERSIST) == 0) + if (state == STATE_UNKNOWN) { + /* From UNKNOWN to UNKNOWN. Persist doesn't apply here. */ + return 0; + } else if ((th->flags & UT_FLAG_PERSIST) == 0) return 0; else if ((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0)) return 0; @@ -367,6 +370,10 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl, snprintf(buf, bufsize, ": All data sources are within range again. " "Current value of \"%s\" is %f.", ds->ds[ds_index].name, values[ds_index]); + } else if (state == STATE_UNKNOWN) { + ERROR("ut_report_state: metric transition to UNKNOWN from a different " + "state. This shouldn't happen."); + return 0; } else { double min; double max; @@ -455,7 +462,7 @@ static int ut_check_one_data_source( if (ds != NULL) { ds_name = ds->ds[ds_index].name; if ((th->data_source[0] != 0) && (strcmp(ds_name, th->data_source) != 0)) - return STATE_OKAY; + return STATE_UNKNOWN; } if ((th->flags & UT_FLAG_INVERT) != 0) { @@ -484,6 +491,7 @@ static int ut_check_one_data_source( case STATE_WARNING: hysteresis_for_warning = th->hysteresis; break; + case STATE_UNKNOWN: case STATE_OKAY: /* do nothing -- the hysteresis only applies to the non-normal states */ break; @@ -525,7 +533,8 @@ static int ut_check_one_data_source( * * Checks all data sources of a value list against the given threshold, using * the ut_check_one_data_source function above. Returns the worst status, - * which is `okay' if nothing has failed. + * which is `okay' if nothing has failed or `unknown' if no valid datasource was + * defined. * Returns less than zero if the data set doesn't have any data sources. */ static int ut_check_one_threshold(const data_set_t *ds, const value_list_t *vl, diff --git a/src/write_riemann_threshold.c b/src/write_riemann_threshold.c index 35f3814a..9d8267dc 100644 --- a/src/write_riemann_threshold.c +++ b/src/write_riemann_threshold.c @@ -63,7 +63,7 @@ static int ut_check_one_data_source( if (ds != NULL) { ds_name = ds->ds[ds_index].name; if ((th->data_source[0] != 0) && (strcmp(ds_name, th->data_source) != 0)) - return STATE_OKAY; + return STATE_UNKNOWN; } if ((th->flags & UT_FLAG_INVERT) != 0) { @@ -73,8 +73,9 @@ static int ut_check_one_data_source( /* 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)) { + prev_state = uc_get_state(ds, vl); + if ((th->hysteresis > 0) && (prev_state != STATE_OKAY) && + (prev_state != STATE_UNKNOWN)) { switch (prev_state) { case STATE_ERROR: if ((!isnan(th->failure_min) &&