From: Florian Forster Date: Mon, 17 Dec 2007 14:37:01 +0000 (+0100) Subject: utils_{cache,threshold}.[ch]: Implemented the ``check interesting'' function. X-Git-Tag: collectd-4.3.0beta0~61 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=1d5a1b3e8e3629c76ba92356ecfa8dfd576e5843;p=collectd.git utils_{cache,threshold}.[ch]: Implemented the ``check interesting'' function. The cache now checks if a missing value would be ``interesting'', i. e. if a threshold is configured for it. If so, a notification is send and the entry is _not_ removed from the cache. Otherwise, no notification is sent and the entry is removed. The changes have been tested a little and should basically work. --- diff --git a/src/utils_cache.c b/src/utils_cache.c index 20d4deb6..b936ace6 100644 --- a/src/utils_cache.c +++ b/src/utils_cache.c @@ -23,6 +23,7 @@ #include "common.h" #include "plugin.h" #include "utils_avltree.h" +#include "utils_threshold.h" #include #include @@ -105,7 +106,7 @@ static int uc_send_notification (const char *name) } /* Check if the entry has been updated in the meantime */ - if ((n.time - ce->last_update) <= (2 * ce->interval)) + if ((n.time - ce->last_update) < (2 * ce->interval)) { pthread_mutex_unlock (&cache_lock); sfree (name_copy); @@ -114,7 +115,7 @@ static int uc_send_notification (const char *name) snprintf (n.message, sizeof (n.message), "%s has not been updated for %i seconds.", name, - (int) (ce->last_update - n.time)); + (int) (n.time - ce->last_update)); pthread_mutex_unlock (&cache_lock); @@ -154,7 +155,7 @@ int uc_check_timeout (void) while (avl_iterator_next (iter, (void *) &key, (void *) &ce) == 0) { /* If entry has not been updated, add to `keys' array */ - if ((now - ce->last_update) > (2 * ce->interval)) + if ((now - ce->last_update) >= (2 * ce->interval)) { char **tmp; @@ -182,21 +183,34 @@ int uc_check_timeout (void) { int status; - /* TODO: Check if value interesting: - * - Not interesting: Remove value from cache and shut up - * - Interesting: Don't remove value from cache but send a - * notification. - */ - status = avl_remove (cache_tree, keys[i], (void *) &key, (void *) &ce); - if (status != 0) + status = ut_check_interesting (keys[i]); + + if (status < 0) { - ERROR ("uc_check_timeout: avl_remove (%s) failed.", keys[i]); - continue; + ERROR ("uc_check_timeout: ut_check_interesting failed."); + sfree (keys[i]); } - - sfree (key); - sfree (ce); - } + else if (status == 0) /* ``service'' is uninteresting */ + { + ce = NULL; + DEBUG ("uc_check_timeout: %s is missing but ``uninteresting''", keys[i]); + status = avl_remove (cache_tree, keys[i], (void *) &key, (void *) &ce); + if (status != 0) + { + ERROR ("uc_check_timeout: avl_remove (%s) failed.", keys[i]); + } + sfree (keys[i]); + sfree (ce); + } + else /* (status > 0); ``service'' is interesting */ + { + /* + * `keys[i]' is not freed and set to NULL, so that the for-loop below + * will send out notifications. There's nothing else to do here. + */ + DEBUG ("uc_check_timeout: %s is missing and ``interesting''", keys[i]); + } + } /* for (keys[i]) */ avl_iterator_destroy (iter); @@ -204,6 +218,9 @@ int uc_check_timeout (void) for (i = 0; i < keys_len; i++) { + if (keys[i] == NULL) + continue; + uc_send_notification (keys[i]); sfree (keys[i]); } @@ -331,6 +348,8 @@ int uc_update (const data_set_t *ds, const value_list_t *vl) } /* for (i) */ ce->last_time = vl->time; + ce->last_update = time (NULL); + ce->interval = vl->interval; if (avl_insert (cache_tree, key, ce) != 0) { diff --git a/src/utils_threshold.c b/src/utils_threshold.c index 1c9ccdd1..8a33e662 100644 --- a/src/utils_threshold.c +++ b/src/utils_threshold.c @@ -471,7 +471,7 @@ int ut_check_threshold (const data_set_t *ds, const value_list_t *vl) if (th == NULL) return (0); - DEBUG ("Found matching threshold"); + DEBUG ("ut_check_threshold: Found matching threshold"); values = uc_get_rate (ds, vl); if (values == NULL) @@ -540,4 +540,66 @@ int ut_check_threshold (const data_set_t *ds, const value_list_t *vl) return (0); } /* int ut_check_threshold */ +int ut_check_interesting (const char *name) +{ + char *name_copy = NULL; + char *host = NULL; + char *plugin = NULL; + char *plugin_instance = NULL; + char *type = NULL; + char *type_instance = NULL; + int status; + data_set_t ds; + value_list_t vl; + threshold_t *th; + + /* If there is no tree nothing is interesting. */ + if (threshold_tree == NULL) + return (0); + + name_copy = strdup (name); + if (name_copy == NULL) + { + ERROR ("ut_check_interesting: strdup failed."); + return (-1); + } + + status = parse_identifier (name_copy, &host, + &plugin, &plugin_instance, &type, &type_instance); + if (status != 0) + { + ERROR ("ut_check_interesting: parse_identifier failed."); + return (-1); + } + + memset (&ds, '\0', sizeof (ds)); + memset (&vl, '\0', sizeof (vl)); + + strncpy (vl.host, host, sizeof (vl.host)); + vl.host[sizeof (vl.host) - 1] = '\0'; + strncpy (vl.plugin, plugin, sizeof (vl.plugin)); + vl.plugin[sizeof (vl.plugin) - 1] = '\0'; + if (plugin_instance != NULL) + { + strncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); + vl.plugin_instance[sizeof (vl.plugin_instance) - 1] = '\0'; + } + strncpy (ds.type, type, sizeof (ds.type)); + ds.type[sizeof (ds.type) - 1] = '\0'; + if (type_instance != NULL) + { + strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.type_instance[sizeof (vl.type_instance) - 1] = '\0'; + } + + sfree (name_copy); + host = plugin = plugin_instance = type = type_instance = NULL; + + th = threshold_search (&ds, &vl); + if (th != NULL) + return (1); + else + return (0); +} /* int ut_check_interesting */ + /* vim: set sw=2 ts=8 sts=2 tw=78 fdm=marker : */ diff --git a/src/utils_threshold.h b/src/utils_threshold.h index 9c347b97..139d6f9f 100644 --- a/src/utils_threshold.h +++ b/src/utils_threshold.h @@ -28,5 +28,6 @@ int ut_config (const oconfig_item_t *ci); int ut_check_threshold (const data_set_t *ds, const value_list_t *vl); +int ut_check_interesting (const char *name); #endif /* UTILS_THRESHOLD_H */