src/utils_threshold.c: Change the percentage code so it works with the DataSource...
[collectd.git] / src / utils_threshold.c
index 083a018..fa8c8f9 100644 (file)
@@ -664,12 +664,12 @@ 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%s.",
-           ds->ds[ds_index].name, values[ds_index],
-           (state == STATE_ERROR) ? "failure" : "warning",
-           min, max,
-           ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE) ? "%" : "" );
+        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
       {
@@ -679,7 +679,7 @@ static int ut_report_state (const data_set_t *ds,
            isnan (min) ? "below" : "above",
            (state == STATE_ERROR) ? "failure" : "warning",
            isnan (min) ? max : min,
-           ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE) ? "%" : "" );
+           ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
       }
     }
     else /* is not inverted */
@@ -690,7 +690,7 @@ static int ut_report_state (const data_set_t *ds,
          (values[ds_index] < min) ? "below" : "above",
          (state == STATE_ERROR) ? "failure" : "warning",
          (values[ds_index] < min) ? min : max,
-         ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE) ? "%" : "" );
+         ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
     }
     buf += status;
     bufsize -= status;
@@ -769,36 +769,49 @@ static int ut_check_one_threshold (const data_set_t *ds,
   int ret = -1;
   int ds_index = -1;
   int i;
+  gauge_t values_copy[ds->ds_num];
 
-  if ((th->flags & UT_FLAG_PERCENTAGE) == UT_FLAG_PERCENTAGE)
-  {
+  memcpy (values_copy, values, sizeof (values_copy));
 
+  if ((th->flags & UT_FLAG_PERCENTAGE) != 0)
+  {
+    int num = 0;
     gauge_t sum=0.0;
-    gauge_t percentage;
 
+    if (ds->ds_num == 1)
+    {
+      WARNING ("ut_check_one_threshold: The %s type has only one data "
+          "source, but you have configured to check this as a percentage. "
+          "That doesn't make much sense, because the percentage will always "
+          "be 100%%!", ds->type);
+    }
+
+    /* Prepare `sum' and `num'. */
     for (i = 0; i < ds->ds_num; i++)
       if (!isnan (values[i]))
+      {
+        num++;
        sum += values[i];
+      }
 
-    if (sum == 0.0)
+    if ((num == 0) /* All data sources are undefined. */
+        || (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */
     {
-      WARNING ("Values sum for percentage seems up to zero");
-      return(STATE_WARNING);
+      for (i = 0; i < ds->ds_num; i++)
+        values_copy[i] = NAN;
     }
-
-    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);
-  }
+    else /* We can actually calculate the percentage. */
+    {
+      for (i = 0; i < ds->ds_num; i++)
+        values_copy[i] = 100.0 * values[i] / sum;
+    }
+  } /* if (UT_FLAG_PERCENTAGE) */
 
   for (i = 0; i < ds->ds_num; i++)
   {
     int status;
 
-    status = ut_check_one_data_source (ds, vl, th, values, i);
+    status = ut_check_one_data_source (ds, vl, th, values_copy, i);
     if (ret < status)
     {
       ret = status;
@@ -950,4 +963,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 : */