#include "plugin.h"
#include "utils_avltree.h"
#include "utils_cache.h"
+#include "utils_threshold.h"
#include <assert.h>
+#include <ltdl.h>
#include <pthread.h>
/*
- * Private data structures
- * {{{ */
-#define UT_FLAG_INVERT 0x01
-#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];
- char plugin[DATA_MAX_NAME_LEN];
- char plugin_instance[DATA_MAX_NAME_LEN];
- char type[DATA_MAX_NAME_LEN];
- char type_instance[DATA_MAX_NAME_LEN];
- char data_source[DATA_MAX_NAME_LEN];
- gauge_t warning_min;
- gauge_t warning_max;
- gauge_t failure_min;
- gauge_t failure_max;
- gauge_t hysteresis;
- unsigned int flags;
- int hits;
- struct threshold_s *next;
-} threshold_t;
-/* }}} */
-
-/*
- * Private (static) variables
- * {{{ */
-static c_avl_tree_t *threshold_tree = NULL;
-static pthread_mutex_t threshold_lock = PTHREAD_MUTEX_INITIALIZER;
-/* }}} */
-
-/*
* Threshold management
* ====================
* The following functions add, delete, search, etc. configured thresholds to
} /* }}} threshold_t *threshold_get */
/*
- * int ut_threshold_add
- *
- * Adds a threshold configuration to the list of thresholds. The threshold_t
- * structure is copied and may be destroyed after this call. Returns zero on
- * success, non-zero otherwise.
- */
-static int ut_threshold_add (const threshold_t *th)
-{ /* {{{ */
- char name[6 * DATA_MAX_NAME_LEN];
- char *name_copy;
- threshold_t *th_copy;
- threshold_t *th_ptr;
- int status = 0;
-
- if (format_name (name, sizeof (name), th->host,
- th->plugin, th->plugin_instance,
- th->type, th->type_instance) != 0)
- {
- ERROR ("ut_threshold_add: format_name failed.");
- return (-1);
- }
-
- name_copy = strdup (name);
- if (name_copy == NULL)
- {
- ERROR ("ut_threshold_add: strdup failed.");
- return (-1);
- }
-
- th_copy = (threshold_t *) malloc (sizeof (threshold_t));
- if (th_copy == NULL)
- {
- sfree (name_copy);
- ERROR ("ut_threshold_add: malloc failed.");
- return (-1);
- }
- memcpy (th_copy, th, sizeof (threshold_t));
- th_ptr = NULL;
-
- DEBUG ("ut_threshold_add: Adding entry `%s'", name);
-
- pthread_mutex_lock (&threshold_lock);
-
- th_ptr = threshold_get (th->host, th->plugin, th->plugin_instance,
- th->type, th->type_instance);
-
- while ((th_ptr != NULL) && (th_ptr->next != NULL))
- th_ptr = th_ptr->next;
-
- if (th_ptr == NULL) /* no such threshold yet */
- {
- status = c_avl_insert (threshold_tree, name_copy, th_copy);
- }
- else /* th_ptr points to the last threshold in the list */
- {
- th_ptr->next = th_copy;
- /* name_copy isn't needed */
- sfree (name_copy);
- }
-
- pthread_mutex_unlock (&threshold_lock);
-
- if (status != 0)
- {
- ERROR ("ut_threshold_add: c_avl_insert (%s) failed.", name);
- sfree (name_copy);
- sfree (th_copy);
- }
-
- return (status);
-} /* }}} int ut_threshold_add */
-
-/*
* threshold_t *threshold_search
*
* Searches for a threshold configuration using all the possible variations of
} /* }}} threshold_t *threshold_search */
/*
- * Configuration
- * =============
- * The following approximately two hundred functions are used to handle the
- * configuration and fill the threshold list.
- * {{{ */
-static int ut_config_type_datasource (threshold_t *th, oconfig_item_t *ci)
-{
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("threshold values: The `DataSource' option needs exactly one "
- "string argument.");
- return (-1);
- }
-
- sstrncpy (th->data_source, ci->values[0].value.string,
- sizeof (th->data_source));
-
- return (0);
-} /* int ut_config_type_datasource */
-
-static int ut_config_type_instance (threshold_t *th, oconfig_item_t *ci)
-{
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("threshold values: The `Instance' option needs exactly one "
- "string argument.");
- return (-1);
- }
-
- sstrncpy (th->type_instance, ci->values[0].value.string,
- sizeof (th->type_instance));
-
- return (0);
-} /* int ut_config_type_instance */
-
-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 `%s' option needs exactly one "
- "number argument.", ci->key);
- return (-1);
- }
-
- if (strcasecmp (ci->key, "WarningMax") == 0)
- th->warning_max = ci->values[0].value.number;
- else
- th->failure_max = ci->values[0].value.number;
-
- return (0);
-} /* int ut_config_type_max */
-
-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 `%s' option needs exactly one "
- "number argument.", ci->key);
- return (-1);
- }
-
- 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 */
-
-static int ut_config_type_hits (threshold_t *th, oconfig_item_t *ci)
-{
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
- {
- WARNING ("threshold values: The `%s' option needs exactly one "
- "number argument.", ci->key);
- return (-1);
- }
-
- th->hits = ci->values[0].value.number;
-
- return (0);
-} /* int ut_config_type_hits */
-
-static int ut_config_type_hysteresis (threshold_t *th, oconfig_item_t *ci)
-{
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
- {
- WARNING ("threshold values: The `%s' option needs exactly one "
- "number argument.", ci->key);
- return (-1);
- }
-
- th->hysteresis = ci->values[0].value.number;
-
- return (0);
-} /* int ut_config_type_hysteresis */
-
-static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci)
-{
- int i;
- threshold_t th;
- int status = 0;
-
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("threshold values: The `Type' block needs exactly one string "
- "argument.");
- return (-1);
- }
-
- if (ci->children_num < 1)
- {
- WARNING ("threshold values: The `Type' block needs at least one option.");
- return (-1);
- }
-
- memcpy (&th, th_orig, sizeof (th));
- sstrncpy (th.type, ci->values[0].value.string, sizeof (th.type));
-
- 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 ("Instance", option->key) == 0)
- status = ut_config_type_instance (&th, option);
- else if (strcasecmp ("DataSource", option->key) == 0)
- status = ut_config_type_datasource (&th, option);
- else if ((strcasecmp ("WarningMax", option->key) == 0)
- || (strcasecmp ("FailureMax", option->key) == 0))
- status = ut_config_type_max (&th, option);
- else if ((strcasecmp ("WarningMin", option->key) == 0)
- || (strcasecmp ("FailureMin", option->key) == 0))
- status = ut_config_type_min (&th, option);
- else if (strcasecmp ("Interesting", option->key) == 0)
- status = cf_util_get_flag (option, &th.flags, UT_FLAG_INTERESTING);
- else if (strcasecmp ("Invert", option->key) == 0)
- 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)
- status = ut_config_type_hits (&th, option);
- else if (strcasecmp ("Hysteresis", option->key) == 0)
- status = ut_config_type_hysteresis (&th, option);
- else
- {
- WARNING ("threshold values: Option `%s' not allowed inside a `Type' "
- "block.", option->key);
- status = -1;
- }
-
- if (status != 0)
- break;
- }
-
- if (status == 0)
- {
- status = ut_threshold_add (&th);
- }
-
- return (status);
-} /* int ut_config_type */
-
-static int ut_config_plugin_instance (threshold_t *th, oconfig_item_t *ci)
-{
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("threshold values: The `Instance' option needs exactly one "
- "string argument.");
- return (-1);
- }
-
- sstrncpy (th->plugin_instance, ci->values[0].value.string,
- sizeof (th->plugin_instance));
-
- return (0);
-} /* int ut_config_plugin_instance */
-
-static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci)
-{
- int i;
- threshold_t th;
- int status = 0;
-
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("threshold values: The `Plugin' block needs exactly one string "
- "argument.");
- return (-1);
- }
-
- if (ci->children_num < 1)
- {
- WARNING ("threshold values: The `Plugin' block needs at least one nested "
- "block.");
- return (-1);
- }
-
- memcpy (&th, th_orig, sizeof (th));
- sstrncpy (th.plugin, ci->values[0].value.string, sizeof (th.plugin));
-
- 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 ("Instance", option->key) == 0)
- status = ut_config_plugin_instance (&th, option);
- else
- {
- WARNING ("threshold values: Option `%s' not allowed inside a `Plugin' "
- "block.", option->key);
- status = -1;
- }
-
- if (status != 0)
- break;
- }
-
- return (status);
-} /* int ut_config_plugin */
-
-static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci)
-{
- int i;
- threshold_t th;
- int status = 0;
-
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("threshold values: The `Host' block needs exactly one string "
- "argument.");
- return (-1);
- }
-
- if (ci->children_num < 1)
- {
- WARNING ("threshold values: The `Host' block needs at least one nested "
- "block.");
- return (-1);
- }
-
- memcpy (&th, th_orig, sizeof (th));
- sstrncpy (th.host, ci->values[0].value.string, sizeof (th.host));
-
- 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
- {
- WARNING ("threshold values: Option `%s' not allowed inside a `Host' "
- "block.", option->key);
- status = -1;
- }
-
- if (status != 0)
- break;
- }
-
- return (status);
-} /* int ut_config_host */
-/*
- * End of the functions used to configure threshold values.
- */
-/* }}} */
-
-/*
* int ut_check_one_data_source
*
* Checks one data source against the given threshold configuration. If the
return (0);
} /* }}} int ut_check_threshold */
-int write_riemann_threshold_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 */
/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */