perf stat: reject --field-separator and --json-output combination

Specifying --field-separator option is stating you want CSV output.
Passing both --field-separator and --json-output is then stating
you want output to be in CSV and JSON format at same time.

Currently this combination is not rejected, and the outcome
is a malformed combination of CSV and JSON output.
This is because of inconsistencies in various printing functions,
some of them have if-else chains that start with
"Should I print JSON?", and some start with "Should I print CSV?".

Example of current output:
$ tools/perf/perf stat -x , -j -e cpu-migrations true
{"counter-value" : "0.000000", "unit" : "", "event" : "cpu-migrations", "event-runtime" : 474817, "pcnt-running" : 100.00,,

Instead reject the option combination,
with a helpful error message and non-zero exit code.

Example of new output:
$ tools/perf/perf stat -x , -j true
cannot use both --field-separator and --json-output

 Usage: perf stat [<options>] [<command>]

    -x, --field-separator <separator>
                          print counts with custom separator
    -j, --json-output     print counts in JSON format

Signed-off-by: Ivan Lazaric <ivan.lazaric1@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Ivan Lazaric 2026-07-08 15:14:01 +02:00 committed by Namhyung Kim
parent eda39f98bb
commit 2612108544
2 changed files with 19 additions and 0 deletions

View File

@ -2655,6 +2655,13 @@ int cmd_stat(int argc, const char **argv)
stat_config.aggr_mode = opt_aggr_mode_to_aggr_mode(&opt_mode);
if (stat_config.csv_sep && stat_config.json_output) {
fprintf(stderr, "cannot use both --field-separator and --json-output\n");
parse_options_usage(stat_usage, stat_options, "x", 1);
parse_options_usage(NULL, stat_options, "j", 1);
goto out;
}
if (stat_config.csv_sep) {
stat_config.csv_output = true;
if (!strcmp(stat_config.csv_sep, "\\t"))

View File

@ -535,6 +535,17 @@ test_stat_delay() {
echo "stat -D test [Success]"
}
test_csv_json_fail() {
echo "stat -x <sep> -j test"
if perf stat -x , -j true > /dev/null 2>&1
then
echo "stat -x <sep> -j test [Failed - command should have errored]"
err=1
else
echo "stat -x <sep> -j test [Success]"
fi
}
test_default_stat
test_null_stat
test_offline_cpu_stat
@ -551,6 +562,7 @@ test_stat_detailed
test_stat_repeat
test_stat_pid
test_stat_delay
test_csv_json_fail
cleanup
exit $err