Skip to content

Commit d81bbea

Browse files
committed
[metrics] Add basic CLI
1 parent e2c1002 commit d81bbea

7 files changed

Lines changed: 328 additions & 81 deletions

File tree

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,6 +2383,7 @@ subdir('src/random-seed')
23832383
subdir('src/rc-local-generator')
23842384
subdir('src/remount-fs')
23852385
subdir('src/repart')
2386+
subdir('src/report')
23862387
subdir('src/reply-password')
23872388
subdir('src/resolve')
23882389
subdir('src/rfkill')

src/core/varlink-metrics.c

Lines changed: 111 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2-
32
#include <assert.h>
43
#include <stdbool.h>
54
#include <string.h>
6-
75
#include "hashmap.h"
86
#include "install.h"
97
#include "json-util.h"
@@ -16,7 +14,7 @@
1614
#include "unit-def.h"
1715
#include "varlink-metrics.h"
1816

19-
static int unit_states_total_build_json_one(
17+
static int units_by_state_total_build_json_one(
2018
sd_varlink *link,
2119
UnitActiveState state,
2220
unsigned count,
@@ -27,13 +25,12 @@ static int unit_states_total_build_json_one(
2725
assert(link);
2826

2927
r = METRIC_JSON_BUILD_UNSIGNED(
30-
&v,
31-
METRIC_IO_SYSTEMD_MANAGER_UNIT_STATES_TOTAL,
32-
/* object= */ NULL,
33-
count,
34-
/* fields */
35-
"state",
36-
unit_active_state_to_string(state));
28+
&v,
29+
METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_STATE_TOTAL,
30+
/* object= */ NULL,
31+
count,
32+
/* fields */ "state",
33+
unit_active_state_to_string(state));
3734
if (r < 0)
3835
return r;
3936

@@ -43,7 +40,29 @@ static int unit_states_total_build_json_one(
4340
return sd_varlink_reply(link, v);
4441
}
4542

46-
static int unit_types_total_build_json_one(sd_varlink *link, Manager *manager, UnitType *type, bool more) {
43+
static int units_by_state_total_build_json(sd_varlink *link, void *userdata, bool more) {
44+
int r;
45+
Manager *manager = ASSERT_PTR(userdata);
46+
47+
assert(link);
48+
49+
r = units_by_state_total_build_json_one(
50+
link,
51+
UNIT_ACTIVE,
52+
hashmap_size(manager->units),
53+
more);
54+
55+
if (r < 0)
56+
return r;
57+
58+
return units_by_state_total_build_json_one(
59+
link,
60+
UNIT_FAILED,
61+
set_size(manager->failed_units),
62+
more);
63+
}
64+
65+
static int units_by_type_total_build_json_one(sd_varlink *link, Manager *manager, UnitType *type, bool more) {
4766
int r;
4867
unsigned count = 0;
4968
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
@@ -58,11 +77,11 @@ static int unit_types_total_build_json_one(sd_varlink *link, Manager *manager, U
5877

5978
r = METRIC_JSON_BUILD_UNSIGNED(
6079
&v,
61-
METRIC_IO_SYSTEMD_MANAGER_UNIT_TYPES_TOTAL,
80+
METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_TYPE_TOTAL,
6281
/* object= */ NULL,
6382
count,
64-
/* fields */
65-
"type", unit_type_to_string(*type));
83+
/* fields */ "type",
84+
unit_type_to_string(*type));
6685
if (r < 0)
6786
return r;
6887

@@ -72,25 +91,43 @@ static int unit_types_total_build_json_one(sd_varlink *link, Manager *manager, U
7291
return sd_varlink_reply(link, v);
7392
}
7493

75-
static int unit_state_build_json_one(sd_varlink *link, Unit *unit, bool more) {
94+
static int units_by_type_total_build_json(sd_varlink *link, void *userdata, bool more) {
95+
int r;
96+
Manager *manager = ASSERT_PTR(userdata);
97+
98+
assert(link);
99+
100+
UnitType *t, *previous_type = NULL;
101+
UnitType type;
102+
for (int i = 0; i < _UNIT_TYPE_MAX; i++) {
103+
type = (UnitType) i;
104+
t = &type;
105+
106+
if (previous_type) {
107+
r = units_by_type_total_build_json_one(link, manager, previous_type, more);
108+
if (r < 0)
109+
return r;
110+
}
111+
112+
previous_type = t;
113+
}
114+
115+
return units_by_type_total_build_json_one(link, manager, previous_type, more);
116+
}
117+
118+
static int unit_active_state_build_json_one(sd_varlink *link, Unit *unit, bool more) {
76119
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
77120
int r;
78121

79122
assert(link);
80123
assert(unit);
81124

82-
83-
r = METRIC_JSON_BUILD_UNSIGNED(
125+
r = METRIC_JSON_BUILD_STRING(
84126
&v,
85-
METRIC_IO_SYSTEMD_MANAGER_UNIT_STATE,
127+
METRIC_IO_SYSTEMD_MANAGER_UNIT_ACTIVE_STATE,
86128
unit->id,
87-
/* value= */ 0, /* 0 is a placeholder and has no meaning */
88-
/* fields */
89-
"state", unit_active_state_to_string(unit_active_state(unit)),
90-
"load_state", unit_load_state_to_string(unit->load_state),
91-
"sub_state", unit_sub_state_to_string(unit),
92-
"freezer_state", freezer_state_to_string(unit->freezer_state),
93-
"unit_file_state", unit_file_state_to_string(unit_get_unit_file_state(unit)));
129+
unit_active_state_to_string(unit_active_state(unit)),
130+
/* fields */ NULL);
94131
if (r < 0)
95132
return r;
96133

@@ -100,71 +137,69 @@ static int unit_state_build_json_one(sd_varlink *link, Unit *unit, bool more) {
100137
return sd_varlink_reply(link, v);
101138
}
102139

103-
static int unit_types_total_build_json(sd_varlink *link, void *userdata, bool more) {
140+
static int unit_active_state_build_json(sd_varlink *link, void *userdata, bool more) {
104141
int r;
142+
const char *k;
143+
Unit *u, *previous = NULL;
105144
Manager *manager = ASSERT_PTR(userdata);
106145

107146
assert(link);
108-
assert(manager);
109-
110-
UnitType *t, *previous_type = NULL;
111-
for (int i = 0; i < _UNIT_TYPE_MAX; i++) {
112-
UnitType type = (UnitType) i;
113-
t = &type;
114147

115-
if (previous_type) {
116-
r = unit_types_total_build_json_one(link, manager, previous_type, more);
148+
HASHMAP_FOREACH_KEY(u, k, manager->units) {
149+
/* ignore aliases */
150+
if (k != u->id)
151+
continue;
152+
if (previous) {
153+
r = unit_active_state_build_json_one(link, previous, /* more = */ true);
117154
if (r < 0)
118155
return r;
119156
}
120157

121-
previous_type = t;
122-
}
158+
previous = u;
159+
}
123160

124-
if (previous_type) {
125-
r = unit_types_total_build_json_one(link, manager, previous_type, more);
126-
if (r < 0)
127-
return r;
128-
} else
129-
return sd_varlink_error(link, VARLINK_ERROR_METRICS_NO_SUCH_METRIC, NULL);
161+
if (previous)
162+
return unit_active_state_build_json_one(link, previous, more);
130163

131-
return 0;
164+
return sd_varlink_error(link, VARLINK_ERROR_METRICS_NO_SUCH_METRIC, NULL);
132165
}
133166

134-
static int unit_states_total_build_json(sd_varlink *link, void *userdata, bool more) {
167+
static int unit_load_state_build_json_one(sd_varlink *link, Unit *unit, bool more) {
168+
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
135169
int r;
136-
Manager *manager = ASSERT_PTR(userdata);
137170

138171
assert(link);
172+
assert(unit);
139173

140-
r = unit_states_total_build_json_one(
141-
link,
142-
UNIT_ACTIVE,
143-
hashmap_size(manager->units),
144-
more);
174+
r = METRIC_JSON_BUILD_STRING(
175+
&v,
176+
METRIC_IO_SYSTEMD_MANAGER_UNIT_LOAD_STATE,
177+
unit->id,
178+
unit_load_state_to_string(unit->load_state),
179+
/* fields */ NULL);
145180
if (r < 0)
146181
return r;
147182

148-
return unit_states_total_build_json_one(
149-
link,
150-
UNIT_FAILED,
151-
set_size(manager->failed_units),
152-
more);
183+
if (more)
184+
return sd_varlink_notify(link, v);
185+
186+
return sd_varlink_reply(link, v);
153187
}
154188

155-
static int unit_state_build_json(sd_varlink *link, void *userdata, bool more) {
189+
static int unit_load_state_build_json(sd_varlink *link, void *userdata, bool more) {
156190
int r;
157191
const char *k;
158192
Unit *u, *previous = NULL;
159193
Manager *manager = ASSERT_PTR(userdata);
160194

195+
assert(link);
196+
161197
HASHMAP_FOREACH_KEY(u, k, manager->units) {
162198
/* ignore aliases */
163199
if (k != u->id)
164200
continue;
165-
166201
if (previous) {
167-
r = unit_state_build_json_one(link, previous, /* more = */ true);
202+
r = unit_load_state_build_json_one(link, previous, /* more = */ true);
168203
if (r < 0)
169204
return r;
170205
}
@@ -173,7 +208,7 @@ static int unit_state_build_json(sd_varlink *link, void *userdata, bool more) {
173208
}
174209

175210
if (previous)
176-
return unit_state_build_json_one(link, previous, more);
211+
return unit_load_state_build_json_one(link, previous, more);
177212

178213
return sd_varlink_error(link, VARLINK_ERROR_METRICS_NO_SUCH_METRIC, NULL);
179214
}
@@ -185,7 +220,6 @@ static int vtable_describe_metrics_build_json_one(sd_varlink *link, const Metric
185220
assert(link);
186221
assert(metric_family);
187222

188-
189223
r = metric_family_json_build(&v, metric_family);
190224
if (r < 0)
191225
return r;
@@ -198,23 +232,26 @@ static int vtable_describe_metrics_build_json_one(sd_varlink *link, const Metric
198232

199233
const MetricFamily metric_family_table[] = {
200234
METRIC_FAMILY(
201-
METRIC_IO_SYSTEMD_MANAGER_UNIT_STATES_TOTAL,
202-
235+
METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_STATE_TOTAL,
203236
"Total counts of units of different states",
204237
METRIC_FAMILY_TYPE_GAUGE,
205-
unit_states_total_build_json),
238+
units_by_state_total_build_json),
206239
METRIC_FAMILY(
207-
METRIC_IO_SYSTEMD_MANAGER_UNIT_TYPES_TOTAL,
240+
METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_TYPE_TOTAL,
208241
"Total counts of units of different types",
209242
METRIC_FAMILY_TYPE_GAUGE,
210-
unit_types_total_build_json),
243+
units_by_type_total_build_json),
211244
METRIC_FAMILY(
212-
METRIC_IO_SYSTEMD_MANAGER_UNIT_STATE,
213-
"Per unit metrics",
214-
METRIC_FAMILY_TYPE_GAUGE,
215-
unit_state_build_json),
245+
METRIC_IO_SYSTEMD_MANAGER_UNIT_ACTIVE_STATE,
246+
"Per unit metrics: active state",
247+
METRIC_FAMILY_TYPE_STRING,
248+
unit_active_state_build_json),
249+
METRIC_FAMILY(
250+
METRIC_IO_SYSTEMD_MANAGER_UNIT_LOAD_STATE,
251+
"Per unit metrics: load state",
252+
METRIC_FAMILY_TYPE_STRING,
253+
unit_load_state_build_json),
216254
{},
217-
218255
};
219256

220257
int vl_method_list(
@@ -237,7 +274,7 @@ int vl_method_list(
237274
const MetricFamily *previous = NULL;
238275
for (const MetricFamily *mf = metric_family_table; mf && mf->name; mf++) {
239276
if (previous) {
240-
r = previous->cb(link, userdata, true);
277+
r = previous->cb(link, userdata, /* more */ true);
241278
if (r < 0)
242279
return log_debug_errno(r, "Failed to list metrics for metric family '%s': %m", previous->name);
243280
}
@@ -246,7 +283,7 @@ int vl_method_list(
246283
}
247284

248285
if (previous) {
249-
r = previous->cb(link, userdata, false);
286+
r = previous->cb(link, userdata, /* more */ false);
250287
if (r < 0)
251288
return log_debug_errno(r, "Failed to list metrics for metric family '%s': %m", previous->name);
252289
}
@@ -274,7 +311,7 @@ int vl_method_describe(
274311
const MetricFamily *previous = NULL;
275312
for (const MetricFamily *mf = metric_family_table; mf && mf->name; mf++) {
276313
if (previous) {
277-
r = vtable_describe_metrics_build_json_one(link, previous, true);
314+
r = vtable_describe_metrics_build_json_one(link, previous, /* more */ true);
278315
if (r < 0)
279316
return log_debug_errno(r, "Failed to describe metric family '%s': %m", previous->name);
280317
}
@@ -283,7 +320,7 @@ int vl_method_describe(
283320
}
284321

285322
if (previous) {
286-
r = vtable_describe_metrics_build_json_one(link, previous, false);
323+
r = vtable_describe_metrics_build_json_one(link, previous, /* more */ false);
287324
if (r < 0)
288325
return log_debug_errno(r, "Failed to describe metric family '%s': %m", previous->name);
289326
}

src/core/varlink-metrics.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
#define VARLINK_ERROR_METRICS_NO_SUCH_METRIC "io.systemd.Metrics.NoSuchMetric"
77

88
#define METRIC_IO_SYSTEMD_MANAGER_PREFIX "io.systemd.Manager."
9-
#define METRIC_IO_SYSTEMD_MANAGER_UNIT_STATES_TOTAL METRIC_IO_SYSTEMD_MANAGER_PREFIX "unit_states_total"
10-
#define METRIC_IO_SYSTEMD_MANAGER_UNIT_TYPES_TOTAL METRIC_IO_SYSTEMD_MANAGER_PREFIX "unit_types_total"
11-
#define METRIC_IO_SYSTEMD_MANAGER_UNIT_STATE METRIC_IO_SYSTEMD_MANAGER_PREFIX "unit_state"
9+
#define METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_STATE_TOTAL METRIC_IO_SYSTEMD_MANAGER_PREFIX "units_by_state_total"
10+
#define METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_TYPE_TOTAL METRIC_IO_SYSTEMD_MANAGER_PREFIX "units_by_type_total"
11+
#define METRIC_IO_SYSTEMD_MANAGER_UNIT_ACTIVE_STATE METRIC_IO_SYSTEMD_MANAGER_PREFIX "unit_active_state"
12+
#define METRIC_IO_SYSTEMD_MANAGER_UNIT_LOAD_STATE METRIC_IO_SYSTEMD_MANAGER_PREFIX "unit_load_state"
1213

1314
int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
1415

src/report/meson.build

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
executables += [
4+
executable_template + {
5+
'name' : 'systemd-report',
6+
'public' : true,
7+
'sources' : files('report.c'),
8+
},
9+
]

0 commit comments

Comments
 (0)