]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
cpu plugin: Aggregate all non-idle states into the "active" state.
authorFlorian Forster <octo@collectd.org>
Fri, 5 Jan 2024 07:30:23 +0000 (08:30 +0100)
committerFlorian Forster <octo@collectd.org>
Mon, 22 Jan 2024 15:07:57 +0000 (16:07 +0100)
src/cpu.c
src/cpu_test.c

index ebf67cd6d6daf9693b565b29f050cff20a34f14c..3856f41a9811a0d9cd5cc34041e25c93d3e0c654 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -402,6 +402,33 @@ __attribute__((unused)) static int usage_record(usage_t *u, size_t cpu,
   return 0;
 }
 
+static gauge_t usage_rate(usage_t u, size_t cpu, state_t state);
+
+static gauge_t usage_active_rate(usage_t u, size_t cpu) {
+  size_t index = (cpu * STATE_MAX) + STATE_ACTIVE;
+  if (index >= u.states_num) {
+    return NAN;
+  }
+
+  usage_state_t us = u.states[index];
+  if (us.has_value) {
+    return us.rate;
+  }
+
+  us.rate = 0;
+  for (state_t s = 0; s < STATE_IDLE; s++) {
+    gauge_t rate = usage_rate(u, cpu, s);
+    if (isnan(rate)) {
+      continue;
+    }
+
+    us.rate += rate;
+    us.has_value = true;
+  }
+
+  return us.has_value ? us.rate : NAN;
+}
+
 __attribute__((unused)) static gauge_t usage_rate(usage_t u, size_t cpu,
                                                   state_t state) {
   size_t index = (cpu * STATE_MAX) + state;
@@ -409,10 +436,12 @@ __attribute__((unused)) static gauge_t usage_rate(usage_t u, size_t cpu,
     return NAN;
   }
 
-  if (!u.states[index].has_value) {
-    return NAN;
+  if (state == STATE_ACTIVE) {
+    return usage_active_rate(u, cpu);
   }
-  return u.states[index].rate;
+
+  usage_state_t us = u.states[index];
+  return us.has_value ? us.rate : NAN;
 }
 
 __attribute__((unused)) static void usage_reset(usage_t *u) {
index ad46a3621afcc73c56c07d2310a089cc76b582a2..6fbae097d9f84b73d07e646d5670e029c70bad03 100644 (file)
@@ -33,6 +33,7 @@ DEF_TEST(usage_simple_rate) {
 
   // Unable to calculate a rate with a single data point.
   EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_USER));
+  EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_ACTIVE));
 
   cdtime_t t1 = t0 + TIME_T_TO_CDTIME_T(10);
   derive_t count_t1 = count_t0 + 100;
@@ -42,9 +43,10 @@ DEF_TEST(usage_simple_rate) {
   usage_record(&usage, 0, STATE_USER, count_t1);
 
   EXPECT_EQ_DOUBLE(want_rate, usage_rate(usage, 0, STATE_USER));
+  EXPECT_EQ_DOUBLE(want_rate, usage_rate(usage, 0, STATE_ACTIVE));
 
   // States that we have not set should be NAN
-  for (state_t s = 0; s < STATE_MAX; s++) {
+  for (state_t s = 0; s < STATE_ACTIVE; s++) {
     if (s == STATE_USER) {
       continue;
     }
@@ -55,8 +57,52 @@ DEF_TEST(usage_simple_rate) {
   return 0;
 }
 
+DEF_TEST(usage_active) {
+  usage_t usage = {0};
+
+  cdtime_t t0 = TIME_T_TO_CDTIME_T(100);
+  derive_t user_t0 = 1000;
+  derive_t syst_t0 = 2000;
+  derive_t idle_t0 = 3000;
+
+  usage_init(&usage, t0);
+  usage_record(&usage, 0, STATE_USER, user_t0);
+  usage_record(&usage, 0, STATE_SYSTEM, syst_t0);
+  usage_record(&usage, 0, STATE_IDLE, idle_t0);
+
+  // Unable to calculate a rate with a single data point.
+  EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_USER));
+  EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_SYSTEM));
+  EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_IDLE));
+  EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_ACTIVE));
+
+  cdtime_t t1 = t0 + TIME_T_TO_CDTIME_T(10);
+  derive_t user_t1 = user_t0 + 200;
+  derive_t syst_t1 = syst_t0 + 100;
+  derive_t idle_t1 = idle_t0 + 700;
+
+  gauge_t want_user_rate = 200.0 / 10.0;
+  gauge_t want_syst_rate = 100.0 / 10.0;
+  gauge_t want_idle_rate = 700.0 / 10.0;
+  gauge_t want_active_rate = want_user_rate + want_syst_rate;
+
+  usage_init(&usage, t1);
+  usage_record(&usage, 0, STATE_USER, user_t1);
+  usage_record(&usage, 0, STATE_SYSTEM, syst_t1);
+  usage_record(&usage, 0, STATE_IDLE, idle_t1);
+
+  EXPECT_EQ_DOUBLE(want_user_rate, usage_rate(usage, 0, STATE_USER));
+  EXPECT_EQ_DOUBLE(want_syst_rate, usage_rate(usage, 0, STATE_SYSTEM));
+  EXPECT_EQ_DOUBLE(want_idle_rate, usage_rate(usage, 0, STATE_IDLE));
+  EXPECT_EQ_DOUBLE(want_active_rate, usage_rate(usage, 0, STATE_ACTIVE));
+
+  usage_reset(&usage);
+  return 0;
+}
+
 int main(void) {
   RUN_TEST(usage_simple_rate);
+  RUN_TEST(usage_active);
 
   END_TEST;
 }