]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
report: add manager-level metrics to varlink Metrics API
authorYaping Li <202858510+YapingLi04@users.noreply.github.com>
Fri, 27 Mar 2026 02:57:46 +0000 (19:57 -0700)
committerYaping Li <202858510+YapingLi04@users.noreply.github.com>
Thu, 2 Apr 2026 20:36:53 +0000 (13:36 -0700)
Added these metrics:

  - JobsQueued: number of jobs currently queued
  - SystemState: overall system state (running, degraded, etc.)
  - UnitsByLoadStateTotal: unit counts broken down by load state
  - UnitsTotal: total number of units

Also bump METRICS_MAX from 1024 to 4096 to accommodate the new
per-unit metrics that are now collected.

src/core/varlink-metrics.c
src/report/report.c

index 00af452d7776c5f5bda0414553d7b24c11e36c96..68560387f30327e8575bdeb8469c6a8352cf388b 100644 (file)
@@ -108,7 +108,7 @@ static int units_by_type_total_build_json(MetricFamilyContext *context, void *us
 
 static int units_by_state_total_build_json(MetricFamilyContext *context, void *userdata) {
         Manager *manager = ASSERT_PTR(userdata);
-        UnitActiveState counters[_UNIT_ACTIVE_STATE_MAX] = {};
+        uint64_t counters[_UNIT_ACTIVE_STATE_MAX] = {};
         Unit *unit;
         char *key;
         int r;
@@ -143,14 +143,109 @@ static int units_by_state_total_build_json(MetricFamilyContext *context, void *u
         return 0;
 }
 
+static int jobs_queued_build_json(MetricFamilyContext *context, void *userdata) {
+        Manager *manager = ASSERT_PTR(userdata);
+
+        assert(context);
+
+        return metric_build_send_unsigned(
+                        context,
+                        /* object= */ NULL,
+                        hashmap_size(manager->jobs),
+                        /* fields= */ NULL);
+}
+
+static int system_state_build_json(MetricFamilyContext *context, void *userdata) {
+        Manager *manager = ASSERT_PTR(userdata);
+
+        assert(context);
+
+        return metric_build_send_string(
+                        context,
+                        /* object= */ NULL,
+                        manager_state_to_string(manager_state(manager)),
+                        /* fields= */ NULL);
+}
+
+static int units_by_load_state_total_build_json(MetricFamilyContext *context, void *userdata) {
+        Manager *manager = ASSERT_PTR(userdata);
+        uint64_t counters[_UNIT_LOAD_STATE_MAX] = {};
+        Unit *unit;
+        char *key;
+        int r;
+
+        assert(context);
+
+        HASHMAP_FOREACH_KEY(unit, key, manager->units) {
+                /* ignore aliases */
+                if (key != unit->id)
+                        continue;
+
+                counters[unit->load_state]++;
+        }
+
+        for (UnitLoadState state = 0; state < _UNIT_LOAD_STATE_MAX; state++) {
+                _cleanup_(sd_json_variant_unrefp) sd_json_variant *fields = NULL;
+
+                r = sd_json_buildo(&fields, SD_JSON_BUILD_PAIR_STRING("load_state", unit_load_state_to_string(state)));
+                if (r < 0)
+                        return r;
+
+                r = metric_build_send_unsigned(
+                                context,
+                                /* object= */ NULL,
+                                counters[state],
+                                fields);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int units_total_build_json(MetricFamilyContext *context, void *userdata) {
+        Manager *manager = ASSERT_PTR(userdata);
+        uint64_t count = 0;
+        Unit *unit;
+        char *key;
+
+        assert(context);
+
+        HASHMAP_FOREACH_KEY(unit, key, manager->units) {
+                /* ignore aliases */
+                if (key != unit->id)
+                        continue;
+
+                count++;
+        }
+
+        return metric_build_send_unsigned(
+                        context,
+                        /* object= */ NULL,
+                        count,
+                        /* fields= */ NULL);
+}
+
 static const MetricFamily metric_family_table[] = {
         /* Keep metrics ordered alphabetically */
+        {
+                .name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "JobsQueued",
+                .description = "Number of jobs currently queued",
+                .type = METRIC_FAMILY_TYPE_GAUGE,
+                .generate = jobs_queued_build_json,
+        },
         {
                 .name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "NRestarts",
                 .description = "Per unit metric: number of restarts",
                 .type = METRIC_FAMILY_TYPE_COUNTER,
                 .generate = nrestarts_build_json,
         },
+        {
+                .name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "SystemState",
+                .description = "Overall system state",
+                .type = METRIC_FAMILY_TYPE_STRING,
+                .generate = system_state_build_json,
+        },
         {
                 .name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "UnitActiveState",
                 .description = "Per unit metric: active state",
@@ -163,6 +258,12 @@ static const MetricFamily metric_family_table[] = {
                 .type = METRIC_FAMILY_TYPE_STRING,
                 .generate = unit_load_state_build_json,
         },
+        {
+                .name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "UnitsByLoadStateTotal",
+                .description = "Total number of units by load state",
+                .type = METRIC_FAMILY_TYPE_GAUGE,
+                .generate = units_by_load_state_total_build_json,
+        },
         {
                 .name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "UnitsByStateTotal",
                 .description = "Total number of units of different state",
@@ -175,6 +276,12 @@ static const MetricFamily metric_family_table[] = {
                 .type = METRIC_FAMILY_TYPE_GAUGE,
                 .generate = units_by_type_total_build_json,
         },
+        {
+                .name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "UnitsTotal",
+                .description = "Total number of units",
+                .type = METRIC_FAMILY_TYPE_GAUGE,
+                .generate = units_total_build_json,
+        },
         {}
 };
 
index 108b24e4701e8c2e1d79162c3947ef15ec494278..ca169c94a8f07f602b9356cc080aaa045cfa48dd 100644 (file)
@@ -27,7 +27,7 @@
 #include "varlink-idl-util.h"
 #include "verbs.h"
 
-#define METRICS_OR_FACTS_MAX 1024U
+#define METRICS_OR_FACTS_MAX 4096U
 #define METRICS_OR_FACTS_LINKS_MAX 128U
 #define TIMEOUT_USEC (30 * USEC_PER_SEC) /* 30 seconds */