* {{{ */
#define UT_FLAG_INVERT 0x01
#define UT_FLAG_PERSIST 0x02
+#define UT_FLAG_PERCENTAGE 0x04
typedef struct threshold_s
{
return (-1);
}
- strncpy (th->type_instance, ci->values[0].value.string,
+ sstrncpy (th->type_instance, ci->values[0].value.string,
sizeof (th->type_instance));
- th->type_instance[sizeof (th->type_instance) - 1] = '\0';
return (0);
} /* int ut_config_type_instance */
return (0);
} /* int ut_config_type_persist */
+static int ut_config_type_percentage(threshold_t *th, oconfig_item_t *ci)
+{
+ if ((ci->values_num != 1)
+ || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN))
+ {
+ WARNING ("threshold values: The `Percentage' option needs exactly one "
+ "boolean argument.");
+ return (-1);
+ }
+
+ if (ci->values[0].value.boolean)
+ th->flags |= UT_FLAG_PERCENTAGE;
+ else
+ th->flags &= ~UT_FLAG_PERCENTAGE;
+
+ return (0);
+} /* int ut_config_type_percentage */
+
static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci)
{
int i;
}
memcpy (&th, th_orig, sizeof (th));
- strncpy (th.type, ci->values[0].value.string, sizeof (th.type));
- th.type[sizeof (th.type) - 1] = '\0';
+ sstrncpy (th.type, ci->values[0].value.string, sizeof (th.type));
th.warning_min = NAN;
th.warning_max = NAN;
status = ut_config_type_invert (&th, option);
else if (strcasecmp ("Persist", option->key) == 0)
status = ut_config_type_persist (&th, option);
+ else if (strcasecmp ("Percentage", option->key) == 0)
+ status = ut_config_type_percentage (&th, option);
else
{
WARNING ("threshold values: Option `%s' not allowed inside a `Type' "
return (-1);
}
- strncpy (th->plugin_instance, ci->values[0].value.string,
+ sstrncpy (th->plugin_instance, ci->values[0].value.string,
sizeof (th->plugin_instance));
- th->plugin_instance[sizeof (th->plugin_instance) - 1] = '\0';
return (0);
} /* int ut_config_plugin_instance */
}
memcpy (&th, th_orig, sizeof (th));
- strncpy (th.plugin, ci->values[0].value.string, sizeof (th.plugin));
- th.plugin[sizeof (th.plugin) - 1] = '\0';
+ sstrncpy (th.plugin, ci->values[0].value.string, sizeof (th.plugin));
for (i = 0; i < ci->children_num; i++)
{
}
memcpy (&th, th_orig, sizeof (th));
- strncpy (th.host, ci->values[0].value.string, sizeof (th.host));
- th.host[sizeof (th.host) - 1] = '\0';
+ sstrncpy (th.host, ci->values[0].value.string, sizeof (th.host));
for (i = 0; i < ci->children_num; i++)
{
th.warning_max = NAN;
th.failure_min = NAN;
th.failure_max = NAN;
-
+
for (i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
*/
/* }}} */
-static threshold_t *threshold_search (const data_set_t *ds,
- const value_list_t *vl)
+static threshold_t *threshold_search (const value_list_t *vl)
{
threshold_t *th;
if ((th = threshold_get (vl->host, vl->plugin, vl->plugin_instance,
- ds->type, vl->type_instance)) != NULL)
+ vl->type, vl->type_instance)) != NULL)
return (th);
else if ((th = threshold_get (vl->host, vl->plugin, vl->plugin_instance,
- ds->type, NULL)) != NULL)
+ vl->type, NULL)) != NULL)
return (th);
else if ((th = threshold_get (vl->host, vl->plugin, NULL,
- ds->type, vl->type_instance)) != NULL)
+ vl->type, vl->type_instance)) != NULL)
return (th);
else if ((th = threshold_get (vl->host, vl->plugin, NULL,
- ds->type, NULL)) != NULL)
+ vl->type, NULL)) != NULL)
return (th);
else if ((th = threshold_get (vl->host, "", NULL,
- ds->type, vl->type_instance)) != NULL)
+ vl->type, vl->type_instance)) != NULL)
return (th);
else if ((th = threshold_get (vl->host, "", NULL,
- ds->type, NULL)) != NULL)
+ vl->type, NULL)) != NULL)
return (th);
else if ((th = threshold_get ("", vl->plugin, vl->plugin_instance,
- ds->type, vl->type_instance)) != NULL)
+ vl->type, vl->type_instance)) != NULL)
return (th);
else if ((th = threshold_get ("", vl->plugin, vl->plugin_instance,
- ds->type, NULL)) != NULL)
+ vl->type, NULL)) != NULL)
return (th);
else if ((th = threshold_get ("", vl->plugin, NULL,
- ds->type, vl->type_instance)) != NULL)
+ vl->type, vl->type_instance)) != NULL)
return (th);
else if ((th = threshold_get ("", vl->plugin, NULL,
- ds->type, NULL)) != NULL)
+ vl->type, NULL)) != NULL)
return (th);
else if ((th = threshold_get ("", "", NULL,
- ds->type, vl->type_instance)) != NULL)
+ vl->type, vl->type_instance)) != NULL)
return (th);
else if ((th = threshold_get ("", "", NULL,
- ds->type, NULL)) != NULL)
+ vl->type, NULL)) != NULL)
return (th);
return (NULL);
n.time = vl->time;
- status = snprintf (buf, bufsize, "Host %s, plugin %s",
+ status = ssnprintf (buf, bufsize, "Host %s, plugin %s",
vl->host, vl->plugin);
buf += status;
bufsize -= status;
if (vl->plugin_instance[0] != '\0')
{
- status = snprintf (buf, bufsize, " (instance %s)",
+ status = ssnprintf (buf, bufsize, " (instance %s)",
vl->plugin_instance);
buf += status;
bufsize -= status;
}
- status = snprintf (buf, bufsize, " type %s", ds->type);
+ status = ssnprintf (buf, bufsize, " type %s", vl->type);
buf += status;
bufsize -= status;
if (vl->type_instance[0] != '\0')
{
- status = snprintf (buf, bufsize, " (instance %s)",
+ status = ssnprintf (buf, bufsize, " (instance %s)",
vl->type_instance);
buf += status;
bufsize -= status;
}
+ plugin_notification_meta_add_string (&n, "DataSource",
+ ds->ds[ds_index].name);
+ plugin_notification_meta_add_double (&n, "CurrentValue", values[ds_index]);
+ plugin_notification_meta_add_double (&n, "WarningMin", th->warning_min);
+ plugin_notification_meta_add_double (&n, "WarningMax", th->warning_max);
+ plugin_notification_meta_add_double (&n, "FailureMin", th->failure_min);
+ plugin_notification_meta_add_double (&n, "FailureMax", th->failure_max);
+
/* Send an okay notification */
if (state == STATE_OKAY)
{
- status = snprintf (buf, bufsize, ": All data sources are within range again.");
+ status = ssnprintf (buf, bufsize, ": All data sources are within range again.");
buf += status;
bufsize -= status;
}
{
if (!isnan (min) && !isnan (max))
{
- status = snprintf (buf, bufsize, ": Data source \"%s\" is currently "
- "%f. That is within the %s region of %f and %f.",
+ status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently "
+ "%f. That is within the %s region of %f and %f%s.",
ds->ds[ds_index].name, values[ds_index],
(state == STATE_ERROR) ? "failure" : "warning",
- min, max);
+ min, max,
+ ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE) ? "%" : "" );
}
else
{
- status = snprintf (buf, bufsize, ": Data source \"%s\" is currently "
- "%f. That is %s the %s threshold of %f.",
+ 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);
+ isnan (min) ? max : min,
+ ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE) ? "%" : "" );
}
}
else /* is not inverted */
{
- status = snprintf (buf, bufsize, ": Data source \"%s\" is currently "
- "%f. That is %s the %s threshold of %f.",
+ 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],
(values[ds_index] < min) ? "below" : "above",
(state == STATE_ERROR) ? "failure" : "warning",
- (values[ds_index] < min) ? min : max);
+ (values[ds_index] < min) ? min : max,
+ ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE) ? "%" : "" );
}
buf += status;
bufsize -= status;
plugin_dispatch_notification (&n);
+ plugin_notification_meta_free (n.meta);
return (0);
} /* }}} int ut_report_state */
* Does not fail.
*/
static int ut_check_one_data_source (const data_set_t *ds,
- const value_list_t *vl,
+ const value_list_t __attribute__((unused)) *vl,
const threshold_t *th,
const gauge_t *values,
int ds_index)
int is_failure = 0;
/* check if this threshold applies to this data source */
- ds_name = ds->ds[ds_index].name;
- if ((th->data_source[0] != 0)
- && (strcmp (ds_name, th->data_source) != 0))
- return (STATE_OKAY);
+ 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);
+ }
if ((th->flags & UT_FLAG_INVERT) != 0)
{
int ds_index = -1;
int i;
+ if ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE)
+ {
+
+ gauge_t sum=0.0;
+ gauge_t percentage;
+
+ for (i = 0; i < ds->ds_num; i++)
+ if (!isnan (values[i]))
+ sum += values[i];
+
+ if (sum == 0.0)
+ {
+ WARNING ("Values sum for percentage seems up to zero");
+ return(STATE_WARNING);
+ }
+
+ percentage = 100.0 * values[0] / sum;
+
+ if (ret_ds_index != NULL)
+ *ret_ds_index = 0;
+
+ return ut_check_one_data_source (NULL, vl, th, &percentage, 0);
+ }
+
for (i = 0; i < ds->ds_num; i++)
{
int status;
/* Is this lock really necessary? So far, thresholds are only inserted at
* startup. -octo */
pthread_mutex_lock (&threshold_lock);
- th = threshold_search (ds, vl);
+ th = threshold_search (vl);
pthread_mutex_unlock (&threshold_lock);
if (th == NULL)
return (0);
return (0);
} /* }}} int ut_check_threshold */
+/*
+ * int ut_check_interesting (PUBLIC)
+ *
+ * Given an identification returns
+ * 0: No threshold is defined.
+ * 1: A threshold has been found. The flag `persist' is off.
+ * 2: A threshold has been found. The flag `persist' is on.
+ * (That is, it is expected that many notifications are sent until the
+ * problem disappears.)
+ */
int ut_check_interesting (const char *name)
-{
+{ /* {{{ */
char *name_copy = NULL;
char *host = NULL;
char *plugin = NULL;
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';
+ sstrncpy (vl.host, host, sizeof (vl.host));
+ sstrncpy (vl.plugin, plugin, sizeof (vl.plugin));
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';
+ sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
+ sstrncpy (ds.type, type, sizeof (ds.type));
+ sstrncpy (vl.type, type, sizeof (vl.type));
if (type_instance != NULL)
- {
- strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
- }
+ sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
sfree (name_copy);
host = plugin = plugin_instance = type = type_instance = NULL;
- th = threshold_search (&ds, &vl);
+ th = threshold_search (&vl);
if (th == NULL)
return (0);
if ((th->flags & UT_FLAG_PERSIST) == 0)
return (1);
return (2);
-} /* int ut_check_interesting */
+} /* }}} int ut_check_interesting */
/* vim: set sw=2 ts=8 sts=2 tw=78 fdm=marker : */