src/utils_threshold.c: Fix a typo.
[collectd.git] / src / utils_threshold.c
index fd6257c..d51789d 100644 (file)
@@ -33,6 +33,7 @@
  * {{{ */
 #define UT_FLAG_INVERT  0x01
 #define UT_FLAG_PERSIST 0x02
+#define UT_FLAG_PERCENTAGE 0x04
 
 typedef struct threshold_s
 {
@@ -262,6 +263,24 @@ static int ut_config_type_persist (threshold_t *th, oconfig_item_t *ci)
   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;
@@ -309,6 +328,8 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci)
       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' "
@@ -467,7 +488,7 @@ int ut_config (const oconfig_item_t *ci)
   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;
@@ -643,30 +664,33 @@ static int ut_report_state (const data_set_t *ds,
     {
       if (!isnan (min) && !isnan (max))
       {
-       status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently "
-           "%f. That is within the %s region of %f and %f.",
-           ds->ds[ds_index].name, values[ds_index],
-           (state == STATE_ERROR) ? "failure" : "warning",
-           min, max);
+        status = 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",
+            min, ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "",
+            max, ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
       }
       else
       {
        status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently "
-           "%f. That is %s the %s threshold of %f.",
+           "%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) != 0) ? "%" : "");
       }
     }
     else /* is not inverted */
     {
       status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently "
-         "%f. That is %s the %s threshold of %f.",
+         "%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) != 0) ? "%" : "");
     }
     buf += status;
     bufsize -= status;
@@ -674,7 +698,7 @@ static int ut_report_state (const data_set_t *ds,
 
   plugin_dispatch_notification (&n);
 
-  plugin_notification_meta_free (&n);
+  plugin_notification_meta_free (n.meta);
   return (0);
 } /* }}} int ut_report_state */
 
@@ -689,7 +713,7 @@ static int ut_report_state (const data_set_t *ds,
  * 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)
@@ -699,10 +723,13 @@ static int ut_check_one_data_source (const data_set_t *ds,
   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)
   {
@@ -743,6 +770,30 @@ static int ut_check_one_threshold (const data_set_t *ds,
   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 sums 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;
@@ -899,4 +950,4 @@ int ut_check_interesting (const char *name)
   return (2);
 } /* }}} int ut_check_interesting */
 
-/* vim: set sw=2 ts=8 sts=2 tw=78 fdm=marker : */
+/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */