From: David Sterba <dsterba@suse.cz>
To: Sidong Yang <realwakka@gmail.com>
Cc: linux-btrfs@vger.kernel.org, dsterba@suse.cz
Subject: Re: [PATCH v3 2/2] btrfs-progs: device stats: add json output format
Date: Fri, 11 Dec 2020 18:30:25 +0100 [thread overview]
Message-ID: <20201211173025.GO6430@twin.jikos.cz> (raw)
In-Reply-To: <20201211164812.459012-2-realwakka@gmail.com>
On Fri, Dec 11, 2020 at 04:48:12PM +0000, Sidong Yang wrote:
> Add supports for json formatting, this patch changes hard coded printing
> code to formatted print with output formatter. Json output would be
> useful for other programs that parse output of the command. but it
> changes the text format.
I did not realize that before, but we can't change the output like that.
That would break fstests.
> Example text format:
>
> device: /dev/vdb
> devid 1
> write_io_errs: 0
> read_io_errs: 0
> flush_io_errs: 0
> corruption_errs: 0
> generation_errs: 0
But at least it's just one more switch that keeps the printf and json
format inside the loop, the rest can stay.
> Example json format:
>
> {
> "__header": {
> "version": "1"
> },
> "device-stats": [
> {
> "device": "/dev/vdb",
> "devid": "1",
> "write_io_errs": "0",
> "read_io_errs": "0",
> "flush_io_errs": "0",
> "corruption_errs": "0",
> "generation_errs": "0"
> }
> ],
^
I've verified that the comma is really there, it's not a valid json so
there's a bug in the formatter. To verify that the output is valid you
can use eg. 'jq', simply pipe the output of the commadn there.
$ ./btrfs --format json dev stats /mnt | jq
parse error: Expected another key-value pair at line 16, column 1
> }
>
> Signed-off-by: Sidong Yang <realwakka@gmail.com>
> ---
> v3:
> - use fmt_print_start_group with NULL name
> ---
> cmds/device.c | 33 +++++++++++++++++++++++++++------
> 1 file changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/cmds/device.c b/cmds/device.c
> index d72881f8..204e834b 100644
> --- a/cmds/device.c
> +++ b/cmds/device.c
> @@ -36,6 +36,7 @@
> #include "common/path-utils.h"
> #include "common/device-utils.h"
> #include "common/device-scan.h"
> +#include "common/format-output.h"
> #include "mkfs/common.h"
>
> static const char * const device_cmd_group_usage[] = {
> @@ -459,6 +460,17 @@ out:
> }
> static DEFINE_SIMPLE_COMMAND(device_ready, "ready");
>
> +static const struct rowspec device_stats_rowspec[] = {
> + { .key = "device", .fmt = "%s", .out_text = "device", .out_json = "device" },
> + { .key = "devid", .fmt = "%u", .out_text = "devid", .out_json = "devid" },
> + { .key = "write_io_errs", .fmt = "%llu", .out_text = "write_io_errs", .out_json = "write_io_errs" },
> + { .key = "read_io_errs", .fmt = "%llu", .out_text = "read_io_errs", .out_json = "read_io_errs" },
> + { .key = "flush_io_errs", .fmt = "%llu", .out_text = "flush_io_errs", .out_json = "flush_io_errs" },
> + { .key = "corruption_errs", .fmt = "%llu", .out_text = "corruption_errs", .out_json = "corruption_errs" },
> + { .key = "generation_errs", .fmt = "%llu", .out_text = "generation_errs", .out_json = "generation_errs" },
> + ROWSPEC_END
> +};
> +
> static const char * const cmd_device_stats_usage[] = {
> "btrfs device stats [options] <path>|<device>",
> "Show device IO error statistics",
The usage help text should also advertise the formats, so this needs the
helpinfo stubs:
--- a/cmds/device.c
+++ b/cmds/device.c
@@ -527,6 +527,8 @@ static const char * const cmd_device_stats_usage[] = {
"",
"-c|--check return non-zero if any stat counter is not zero",
"-z|--reset show current stats and reset values to zero",
+ HELPINFO_INSERT_GLOBALS,
+ HELPINFO_INSERT_FORMAT,
NULL
};
---
> @@ -482,6 +494,7 @@ static int cmd_device_stats(const struct cmd_struct *cmd, int argc, char **argv)
> int check = 0;
> __u64 flags = 0;
> DIR *dirstream = NULL;
> + struct format_ctx fctx;
>
> optind = 0;
> while (1) {
> @@ -530,6 +543,8 @@ static int cmd_device_stats(const struct cmd_struct *cmd, int argc, char **argv)
> goto out;
> }
>
> + fmt_start(&fctx, device_stats_rowspec, 24, 0);
> + fmt_print_start_group(&fctx, "device-stats", JSON_TYPE_ARRAY);
> for (i = 0; i < fi_args.num_devices; i++) {
> struct btrfs_ioctl_get_dev_stats args = {0};
> char path[BTRFS_DEVICE_PATH_NAME_MAX + 1];
> @@ -548,6 +563,7 @@ static int cmd_device_stats(const struct cmd_struct *cmd, int argc, char **argv)
> err |= 1;
> } else {
> char *canonical_path;
> + char devid_str[32];
> int j;
> static const struct {
> const char name[32];
> @@ -574,31 +590,36 @@ static int cmd_device_stats(const struct cmd_struct *cmd, int argc, char **argv)
> snprintf(canonical_path, 32,
> "devid:%llu", args.devid);
> }
> + snprintf(devid_str, 32, "%llu", args.devid);
> + fmt_print_start_group(&fctx, NULL, JSON_TYPE_MAP);
> + fmt_print(&fctx, "device", canonical_path);
> + fmt_print(&fctx, "devid", di_args[i].devid);
>
> for (j = 0; j < ARRAY_SIZE(dev_stats); j++) {
> /* We got fewer items than we know */
> if (args.nr_items < dev_stats[j].num + 1)
> continue;
> - printf("[%s].%-16s %llu\n", canonical_path,
> - dev_stats[j].name,
> - (unsigned long long)
> - args.values[dev_stats[j].num]);
> +
> + fmt_print(&fctx, dev_stats[j].name, args.values[dev_stats[j].num]);
So the switch goes here
> if ((check == 1)
> && (args.values[dev_stats[j].num] > 0))
> err |= 64;
> }
> -
> + fmt_print_end_group(&fctx, NULL);
> free(canonical_path);
> }
> }
>
> + fmt_print_end_group(&fctx, "device-stats");
> + fmt_end(&fctx);
> +
> out:
> free(di_args);
> close_file_or_dir(fdmnt, dirstream);
>
> return err;
> }
> -static DEFINE_SIMPLE_COMMAND(device_stats, "stats");
> +static DEFINE_COMMAND_WITH_FLAGS(device_stats, "stats", CMD_FORMAT_JSON);
>
> static const char * const cmd_device_usage_usage[] = {
> "btrfs device usage [options] <path> [<path>..]",
> --
> 2.25.1
next prev parent reply other threads:[~2020-12-11 19:16 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-11 16:48 [PATCH v3 1/2] btrfs-progs: common: extend fmt_print_start_group handles unnamed group Sidong Yang
2020-12-11 16:48 ` [PATCH v3 2/2] btrfs-progs: device stats: add json output format Sidong Yang
2020-12-11 17:30 ` David Sterba [this message]
2020-12-11 17:46 ` David Sterba
2020-12-11 18:09 ` Sidong Yang
2020-12-16 17:23 ` David Sterba
2020-12-16 17:41 ` David Sterba
2020-12-16 6:30 ` Su Yue
2020-12-16 10:52 ` Sidong Yang
2020-12-16 12:52 ` Su Yue
2020-12-16 17:21 ` David Sterba
2020-12-16 17:18 ` David Sterba
2020-12-11 17:31 ` [PATCH v3 1/2] btrfs-progs: common: extend fmt_print_start_group handles unnamed group David Sterba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201211173025.GO6430@twin.jikos.cz \
--to=dsterba@suse.cz \
--cc=linux-btrfs@vger.kernel.org \
--cc=realwakka@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox