core/varlink-metrics: expose ReloadCount as a metric
Add ReloadCount to the io.systemd.Metrics family table so it can be queried alongside other manager-level metrics via systemd-report. Also extend the existing integration test to cross-check the value returned by systemd-report against the D-Bus and Varlink transports on every assertion. Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Simon Lucido <simonlucido@meta.com>
This commit is contained in:
committed by
Luca Boccassi
parent
2d9d62f658
commit
71ebb27686
@@ -189,6 +189,18 @@ static int nrestarts_build_json(MetricFamilyContext *context, void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reload_count_build_json(MetricFamilyContext *context, void *userdata) {
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
|
||||
assert(context);
|
||||
|
||||
return metric_build_send_unsigned(
|
||||
context,
|
||||
/* object= */ NULL,
|
||||
manager->reload_count,
|
||||
/* fields= */ NULL);
|
||||
}
|
||||
|
||||
static int units_by_type_total_build_json(MetricFamilyContext *context, void *userdata) {
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
@@ -364,6 +376,12 @@ static const MetricFamily metric_family_table[] = {
|
||||
.type = METRIC_FAMILY_TYPE_COUNTER,
|
||||
.generate = nrestarts_build_json,
|
||||
},
|
||||
{
|
||||
.name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "ReloadCount",
|
||||
.description = "Number of successful manager reloads since startup; resets across daemon-reexec",
|
||||
.type = METRIC_FAMILY_TYPE_COUNTER,
|
||||
.generate = reload_count_build_json,
|
||||
},
|
||||
{
|
||||
.name = METRIC_IO_SYSTEMD_MANAGER_PREFIX "StateChangeTimestamp",
|
||||
.description = "Per unit metric: timestamp of the last state change in microseconds; 0 indicates no state change has occurred",
|
||||
|
||||
@@ -5,7 +5,13 @@ set -o pipefail
|
||||
|
||||
# Verify that the manager exposes a ReloadCount property that increments on
|
||||
# every daemon-reload, resets to zero across daemon-reexec (since the count
|
||||
# is not serialized), and is reachable over both D-Bus and Varlink.
|
||||
# is not serialized), and is reachable over D-Bus, Varlink Describe, and the
|
||||
# io.systemd.Metrics interface (queried via systemd-report).
|
||||
|
||||
# systemd-report silently returns empty if the metrics source is missing,
|
||||
# which would falsely pass the cross-checks below. Assert the socket exists
|
||||
# so any failure points at the real problem.
|
||||
test -S /run/systemd/report/io.systemd.Manager
|
||||
|
||||
read_count_dbus() {
|
||||
busctl -j get-property org.freedesktop.systemd1 \
|
||||
@@ -19,10 +25,23 @@ read_count_varlink() {
|
||||
io.systemd.Manager.Describe '{}' | jq -r '.runtime.ReloadCount'
|
||||
}
|
||||
|
||||
# Sanity: both transports must agree.
|
||||
read_count_report() {
|
||||
local out
|
||||
# Strip the RS separator that jq --seq re-emits on output.
|
||||
out=$(/usr/lib/systemd/systemd-report metrics --json=short \
|
||||
io.systemd.Manager.ReloadCount \
|
||||
| jq --seq -r 'select(.name == "io.systemd.Manager.ReloadCount") | .value' \
|
||||
| tr -d '\036')
|
||||
[[ -n "$out" ]] || { echo "ReloadCount metric missing from systemd-report output" >&2; return 1; }
|
||||
echo "$out"
|
||||
}
|
||||
|
||||
# Sanity: all three transports must agree.
|
||||
dbus_count=$(read_count_dbus)
|
||||
varlink_count=$(read_count_varlink)
|
||||
report_count=$(read_count_report)
|
||||
(( dbus_count == varlink_count ))
|
||||
(( dbus_count == report_count ))
|
||||
|
||||
# A single reload bumps the counter by one.
|
||||
before=$(read_count_dbus)
|
||||
@@ -34,18 +53,22 @@ systemctl daemon-reload
|
||||
systemctl daemon-reload
|
||||
(( $(read_count_dbus) == before + 3 ))
|
||||
|
||||
# And both transports still agree after the reload.
|
||||
# And all three transports still agree after the reload.
|
||||
dbus_count=$(read_count_dbus)
|
||||
varlink_count=$(read_count_varlink)
|
||||
report_count=$(read_count_report)
|
||||
(( dbus_count == varlink_count ))
|
||||
(( dbus_count == report_count ))
|
||||
|
||||
# A daemon-reexec resets the counter back to zero on both transports, since
|
||||
# reload_count lives only in memory and is not carried across the reexec.
|
||||
# A daemon-reexec resets the counter back to zero on all three transports,
|
||||
# since the counter lives only in memory and is not carried across the reexec.
|
||||
# `systemctl daemon-reexec` returns as soon as the old PID 1 closes its bus
|
||||
# connection, which is before the new PID 1 has rebound /run/systemd/private.
|
||||
# Use --watch-bind=yes to block on inotify until the new socket is live.
|
||||
systemctl daemon-reexec
|
||||
busctl --watch-bind=yes call org.freedesktop.systemd1 /org/freedesktop/systemd1 \
|
||||
org.freedesktop.DBus.Peer Ping >/dev/null
|
||||
|
||||
(( $(read_count_dbus) == 0 ))
|
||||
(( $(read_count_varlink) == 0 ))
|
||||
(( $(read_count_report) == 0 ))
|
||||
|
||||
Reference in New Issue
Block a user