X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fthreshold.c;h=c1af40b81e019e967026cf43c3e40be1a97954c1;hb=73326703f6cc6d7edd6ab8d8224840ed0a8f1963;hp=7bbc59ef011a5f4a597b524f54a10852f1b725bf;hpb=cc0bb2b472628ccede974a02c822d1f9189f0d21;p=collectd.git diff --git a/src/threshold.c b/src/threshold.c index 7bbc59ef..c1af40b8 100644 --- a/src/threshold.c +++ b/src/threshold.c @@ -39,6 +39,7 @@ #define UT_FLAG_PERSIST 0x02 #define UT_FLAG_PERCENTAGE 0x04 #define UT_FLAG_INTERESTING 0x08 +#define UT_FLAG_PERSIST_OK 0x10 typedef struct threshold_s { char host[DATA_MAX_NAME_LEN]; @@ -360,7 +361,6 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci) for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - status = 0; if (strcasecmp ("Instance", option->key) == 0) status = ut_config_type_instance (&th, option); @@ -378,6 +378,8 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci) status = cf_util_get_flag (option, &th.flags, UT_FLAG_INVERT); else if (strcasecmp ("Persist", option->key) == 0) status = cf_util_get_flag (option, &th.flags, UT_FLAG_PERSIST); + else if (strcasecmp ("PersistOK", option->key) == 0) + status = cf_util_get_flag (option, &th.flags, UT_FLAG_PERSIST_OK); else if (strcasecmp ("Percentage", option->key) == 0) status = cf_util_get_flag (option, &th.flags, UT_FLAG_PERCENTAGE); else if (strcasecmp ("Hits", option->key) == 0) @@ -446,7 +448,6 @@ static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci) for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - status = 0; if (strcasecmp ("Type", option->key) == 0) status = ut_config_type (&th, option); @@ -493,7 +494,6 @@ static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci) for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - status = 0; if (strcasecmp ("Type", option->key) == 0) status = ut_config_type (&th, option); @@ -512,57 +512,6 @@ static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci) return (status); } /* int ut_config_host */ - -int ut_config (oconfig_item_t *ci) -{ - int i; - int status = 0; - - threshold_t th; - - if (threshold_tree == NULL) - { - threshold_tree = c_avl_create ((void *) strcmp); - if (threshold_tree == NULL) - { - ERROR ("ut_config: c_avl_create failed."); - return (-1); - } - } - - memset (&th, '\0', sizeof (th)); - th.warning_min = NAN; - th.warning_max = NAN; - th.failure_min = NAN; - th.failure_max = NAN; - - th.hits = 0; - th.hysteresis = 0; - th.flags = UT_FLAG_INTERESTING; /* interesting by default */ - - for (i = 0; i < ci->children_num; i++) - { - oconfig_item_t *option = ci->children + i; - status = 0; - - if (strcasecmp ("Type", option->key) == 0) - status = ut_config_type (&th, option); - else if (strcasecmp ("Plugin", option->key) == 0) - status = ut_config_plugin (&th, option); - else if (strcasecmp ("Host", option->key) == 0) - status = ut_config_host (&th, option); - else - { - WARNING ("threshold values: Option `%s' not allowed here.", option->key); - status = -1; - } - - if (status != 0) - break; - } - - return (status); -} /* int um_config */ /* * End of the functions used to configure threshold values. */ @@ -594,8 +543,9 @@ static int ut_report_state (const data_set_t *ds, if ( (th->hits != 0) ) { int hits = uc_get_hits(ds,vl); - /* The STATE_OKAY always reset hits, or if hits reaise the limit */ - if ( (state == STATE_OKAY) || (hits > th->hits) ) + /* STATE_OKAY resets hits unless PERSIST_OK flag is set. Hits resets if + * threshold is hit. */ + if ( ( (state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0) ) || (hits > th->hits) ) { DEBUG("ut_report_state: reset uc_get_hits = 0"); uc_set_hits(ds,vl,0); /* reset hit counter and notify */ @@ -608,13 +558,13 @@ static int ut_report_state (const data_set_t *ds, state_old = uc_get_state (ds, vl); - /* If the state didn't change, only report if `persistent' is specified and - * the state is not `okay'. */ + /* 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) return (0); - else if (state == STATE_OKAY) + else if ( (state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0) ) return (0); } @@ -672,13 +622,9 @@ static int ut_report_state (const data_set_t *ds, if (state == STATE_OKAY) { if (state_old == STATE_MISSING) - status = ssnprintf (buf, bufsize, - ": Value is no longer missing."); + ssnprintf (buf, bufsize, ": Value is no longer missing."); else - status = ssnprintf (buf, bufsize, - ": All data sources are within range again."); - buf += status; - bufsize -= status; + ssnprintf (buf, bufsize, ": All data sources are within range again."); } else { @@ -692,7 +638,7 @@ static int ut_report_state (const data_set_t *ds, { if (!isnan (min) && !isnan (max)) { - status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " + ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " "%f. That is within the %s region of %f%s and %f%s.", ds->ds[ds_index].name, values[ds_index], (state == STATE_ERROR) ? "failure" : "warning", @@ -701,13 +647,13 @@ static int ut_report_state (const data_set_t *ds, } else { - status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%f. That is %s the %s threshold of %f%s.", - ds->ds[ds_index].name, values[ds_index], - isnan (min) ? "below" : "above", - (state == STATE_ERROR) ? "failure" : "warning", - isnan (min) ? max : min, - ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); + ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " + "%f. That is %s the %s threshold of %f%s.", + ds->ds[ds_index].name, values[ds_index], + isnan (min) ? "below" : "above", + (state == STATE_ERROR) ? "failure" : "warning", + isnan (min) ? max : min, + ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); } } else if (th->flags & UT_FLAG_PERCENTAGE) @@ -730,7 +676,7 @@ static int ut_report_state (const data_set_t *ds, else value = 100.0 * values[ds_index] / sum; - status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " + ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " "%g (%.2f%%). That is %s the %s threshold of %.2f%%.", ds->ds[ds_index].name, values[ds_index], value, (value < min) ? "below" : "above", @@ -739,15 +685,13 @@ static int ut_report_state (const data_set_t *ds, } else /* is not inverted */ { - status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%f. That is %s the %s threshold of %f.", - ds->ds[ds_index].name, values[ds_index], - (values[ds_index] < min) ? "below" : "above", - (state == STATE_ERROR) ? "failure" : "warning", - (values[ds_index] < min) ? min : max); + ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " + "%f. That is %s the %s threshold of %f.", + ds->ds[ds_index].name, values[ds_index], + (values[ds_index] < min) ? "below" : "above", + (state == STATE_ERROR) ? "failure" : "warning", + (values[ds_index] < min) ? min : max); } - buf += status; - bufsize -= status; } plugin_dispatch_notification (&n); @@ -989,31 +933,94 @@ 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); th = threshold_search (vl); - if (th == NULL) + /* dispatch notifications for "interesting" values only */ + 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); return (0); } /* }}} int ut_missing */ +static int ut_config (oconfig_item_t *ci) +{ /* {{{ */ + int i; + int status = 0; + int old_size = c_avl_size (threshold_tree); + + threshold_t th; + + if (threshold_tree == NULL) + { + threshold_tree = c_avl_create ((void *) strcmp); + if (threshold_tree == NULL) + { + ERROR ("ut_config: c_avl_create failed."); + return (-1); + } + } + + memset (&th, '\0', sizeof (th)); + th.warning_min = NAN; + th.warning_max = NAN; + th.failure_min = NAN; + th.failure_max = NAN; + + th.hits = 0; + th.hysteresis = 0; + th.flags = UT_FLAG_INTERESTING; /* interesting by default */ + + for (i = 0; i < ci->children_num; i++) + { + oconfig_item_t *option = ci->children + i; + + if (strcasecmp ("Type", option->key) == 0) + status = ut_config_type (&th, option); + else if (strcasecmp ("Plugin", option->key) == 0) + status = ut_config_plugin (&th, option); + else if (strcasecmp ("Host", option->key) == 0) + status = ut_config_host (&th, option); + else + { + WARNING ("threshold values: Option `%s' not allowed here.", option->key); + status = -1; + } + + if (status != 0) + break; + } + + /* register callbacks if this is the first time we see a valid config */ + if ((old_size == 0) && (c_avl_size (threshold_tree) > 0)) + { + plugin_register_missing ("threshold", ut_missing, + /* user data = */ NULL); + plugin_register_write ("threshold", ut_check_threshold, + /* user data = */ NULL); + } + + return (status); +} /* }}} int um_config */ + void module_register (void) { plugin_register_complex_config ("threshold", ut_config); - plugin_register_missing ("threshold", ut_missing, - /* user data = */ NULL); - plugin_register_write ("threshold", ut_check_threshold, - /* user data = */ NULL); } /* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */