From: Lennart Poettering Date: Wed, 18 Feb 2026 10:19:35 +0000 (+0100) Subject: report: switch to "verbs" command line interface, and add 'describe-metrics' X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5046a12fbcd24d208bbca02b229a8ddd0465d28d;p=thirdparty%2Fsystemd.git report: switch to "verbs" command line interface, and add 'describe-metrics' Let's prepare for a future where the "systemd-report" tool can do more than enumerate metrics: let's introduce our usual "verbs" style interface. Let's also add a second command right-away: "describe-metrics" shows the description of the metrics. --- diff --git a/man/systemd-report.xml b/man/systemd-report.xml index f786f0eb72c..13c4958b033 100644 --- a/man/systemd-report.xml +++ b/man/systemd-report.xml @@ -37,6 +37,33 @@ standard output. + + Commands + + The following commands are understood: + + + + metrics + + Acquire a list of metrics values from all local services providing them, and write them to standard output. + + + + + + describe-metrics + + Acquire a list of metric families from all local services providing them, and write + them to standard output. This returns information about metrics, their data types and human readable + description without values. + + + + + + + Options diff --git a/src/report/report.c b/src/report/report.c index fe4b96c5f0f..d8e262049af 100644 --- a/src/report/report.c +++ b/src/report/report.c @@ -19,7 +19,9 @@ #include "set.h" #include "sort-util.h" #include "string-util.h" +#include "strv.h" #include "time-util.h" +#include "verbs.h" #define METRICS_MAX 1024U #define METRICS_LINKS_MAX 128U @@ -28,7 +30,15 @@ static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_PRETTY_AUTO|SD_JSON_FORMAT_COLOR_AUTO; +typedef enum Action { + ACTION_LIST, + ACTION_DESCRIBE, + _ACTION_MAX, + _ACTION_INVALID = -EINVAL, +} Action; + typedef struct Context { + Action action; sd_event *event; Set *link_infos; sd_json_variant **metrics; /* Collected metrics for sorting */ @@ -204,9 +214,12 @@ static int metrics_call(Context *context, const char *path) { if (r < 0) return log_error_errno(r, "Failed to bind reply callback: %m"); - r = sd_varlink_observe(vl, "io.systemd.Metrics.List", /* parameters= */ NULL); + const char *method = context->action == ACTION_LIST ? "io.systemd.Metrics.List" : "io.systemd.Metrics.Describe"; + r = sd_varlink_observe(vl, + method, + /* parameters= */ NULL); if (r < 0) - return log_error_errno(r, "Failed to issue io.systemd.Metrics.List call: %m"); + return log_error_errno(r, "Failed to issue %s() call: %m", method); _cleanup_(link_info_freep) LinkInfo *li = new(LinkInfo, 1); if (!li) @@ -252,17 +265,30 @@ static int metrics_output_sorted(Context *context) { return 0; } -static int metrics_query(void) { +static int verb_metrics(int argc, char *argv[], void *userdata) { + Action action; int r; + assert(argc == 1); + assert(argv); + + if (streq_ptr(argv[0], "metrics")) + action = ACTION_LIST; + else { + assert(streq_ptr(argv[0], "describe-metrics")); + action = ACTION_DESCRIBE; + } + _cleanup_free_ char *metrics_path = NULL; r = runtime_directory_generic(arg_runtime_scope, "systemd/report", &metrics_path); if (r < 0) return log_error_errno(r, "Failed to determine metrics directory path: %m"); - log_debug("Looking for reports in %s/", metrics_path); + log_debug("Looking for metrics in %s/", metrics_path); - _cleanup_(context_done) Context context = {}; + _cleanup_(context_done) Context context = { + .action = action, + }; r = sd_event_default(&context.event); if (r < 0) @@ -323,7 +349,7 @@ static int metrics_query(void) { return 0; } -static int help(void) { +static int verb_help(int argc, char *argv[], void *userdata) { _cleanup_free_ char *link = NULL; int r; @@ -331,19 +357,25 @@ static int help(void) { if (r < 0) return log_oom(); - printf("%s [OPTIONS...] \n\n" - "%sPrint metrics for all system components.%s\n\n" + printf("%1$s [OPTIONS...] COMMAND ...\n" + "\n%5$sAcquire metrics from local sources.%6$s\n" + "\n%3$sCommands:%4$s\n" + " metrics Acquire list of metrics and their values\n" + " describe-metrics Describe available metrics\n" + "\n%3$sOptions:%4$s\n" " -h --help Show this help\n" " --version Show package version\n" " --user Connect to user service manager\n" " --system Connect to system service manager (default)\n" " --json=pretty|short\n" " Configure JSON output\n" - "\nSee the %s for details.\n", + "\nSee the %2$s for details.\n", program_invocation_short_name, - ansi_highlight(), + link, + ansi_underline(), ansi_normal(), - link); + ansi_highlight(), + ansi_normal()); return 0; } @@ -373,7 +405,7 @@ static int parse_argv(int argc, char *argv[]) { while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': - return help(); + return verb_help(/* argc= */ 0, /* argv= */ NULL, /* userdata= */ NULL); case ARG_VERSION: return version(); @@ -400,15 +432,22 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached(); } - if (optind < argc) - return log_error_errno( - SYNTHETIC_ERRNO(EINVAL), - "%s takes no arguments.", - program_invocation_short_name); - return 1; } + +static int report_main(int argc, char *argv[]) { + + static const Verb verbs[] = { + { "help", VERB_ANY, 1, 0, verb_help }, + { "metrics", VERB_ANY, 1, 0, verb_metrics }, + { "describe-metrics", VERB_ANY, 1, 0, verb_metrics }, + {} + }; + + return dispatch_verb(argc, argv, verbs, NULL); +} + static int run(int argc, char *argv[]) { int r; @@ -418,7 +457,7 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; - return metrics_query(); + return report_main(argc, argv); } DEFINE_MAIN_FUNCTION(run); diff --git a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh index 377c4734e06..d72acc59497 100755 --- a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh +++ b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh @@ -244,7 +244,7 @@ systemd-run --wait --pipe --user --machine testuser@ \ varlinkctl --more call "/run/user/$testuser_uid/systemd/io.systemd.Manager" io.systemd.Unit.List '{}' # test report -systemd-report +systemd-report metrics # test io.systemd.Network Metrics varlinkctl info /run/systemd/report/io.systemd.Network