Commit df936cad authored by Claire Jensen's avatar Claire Jensen Committed by Arnaldo Carvalho de Melo

perf stat: Add JSON output option

CSV output is tricky to format and column layout changes are susceptible
to breaking parsers. New JSON-formatted output has variable names to
identify fields that are consistent and informative, making the output
parseable.

CSV output example:

  1.20,msec,task-clock:u,1204272,100.00,0.697,CPUs utilized
  0,,context-switches:u,1204272,100.00,0.000,/sec
  0,,cpu-migrations:u,1204272,100.00,0.000,/sec
  70,,page-faults:u,1204272,100.00,58.126,K/sec

JSON output example:

  {"counter-value" : "3805.723968", "unit" : "msec", "event" :
  "cpu-clock", "event-runtime" : 3805731510100.00, "pcnt-running"
  : 100.00, "metric-value" : 4.007571, "metric-unit" : "CPUs utilized"}
  {"counter-value" : "6166.000000", "unit" : "", "event" :
  "context-switches", "event-runtime" : 3805723045100.00, "pcnt-running"
  : 100.00, "metric-value" : 1.620191, "metric-unit" : "K/sec"}
  {"counter-value" : "466.000000", "unit" : "", "event" :
  "cpu-migrations", "event-runtime" : 3805727613100.00, "pcnt-running"
  : 100.00, "metric-value" : 122.447136, "metric-unit" : "/sec"}
  {"counter-value" : "208.000000", "unit" : "", "event" :
  "page-faults", "event-runtime" : 3805726799100.00, "pcnt-running"
  : 100.00, "metric-value" : 54.654516, "metric-unit" : "/sec"}

Also added documentation for JSON option.

There is some tidy up of CSV code including a potential memory over run
in the os.nfields set up. To facilitate this an AGGR_MAX value is added.

Committer notes:

Fixed up using PRIu64 to format u64 values, not %lu.

Committer testing:

  ⬢[acme@toolbox perf]$ perf stat -j sleep 1
  {"counter-value" : "0.731750", "unit" : "msec", "event" : "task-clock:u", "event-runtime" : 731750, "pcnt-running" : 100.00, "metric-value" : 0.000731, "metric-unit" : "CPUs utilized"}
  {"counter-value" : "0.000000", "unit" : "", "event" : "context-switches:u", "event-runtime" : 731750, "pcnt-running" : 100.00, "metric-value" : 0.000000, "metric-unit" : "/sec"}
  {"counter-value" : "0.000000", "unit" : "", "event" : "cpu-migrations:u", "event-runtime" : 731750, "pcnt-running" : 100.00, "metric-value" : 0.000000, "metric-unit" : "/sec"}
  {"counter-value" : "75.000000", "unit" : "", "event" : "page-faults:u", "event-runtime" : 731750, "pcnt-running" : 100.00, "metric-value" : 102.494021, "metric-unit" : "K/sec"}
  {"counter-value" : "578765.000000", "unit" : "", "event" : "cycles:u", "event-runtime" : 379366, "pcnt-running" : 49.00, "metric-value" : 0.790933, "metric-unit" : "GHz"}
  {"counter-value" : "1298.000000", "unit" : "", "event" : "stalled-cycles-frontend:u", "event-runtime" : 768020, "pcnt-running" : 100.00, "metric-value" : 0.224271, "metric-unit" : "frontend cycles idle"}
  {"counter-value" : "21984.000000", "unit" : "", "event" : "stalled-cycles-backend:u", "event-runtime" : 768020, "pcnt-running" : 100.00, "metric-value" : 3.798433, "metric-unit" : "backend cycles idle"}
  {"counter-value" : "468197.000000", "unit" : "", "event" : "instructions:u", "event-runtime" : 768020, "pcnt-running" : 100.00, "metric-value" : 0.808959, "metric-unit" : "insn per cycle"}
  {"metric-value" : 0.046955, "metric-unit" : "stalled cycles per insn"}
  {"counter-value" : "103335.000000", "unit" : "", "event" : "branches:u", "event-runtime" : 768020, "pcnt-running" : 100.00, "metric-value" : 141.216262, "metric-unit" : "M/sec"}
  {"counter-value" : "2381.000000", "unit" : "", "event" : "branch-misses:u", "event-runtime" : 388654, "pcnt-running" : 50.00, "metric-value" : 2.304156, "metric-unit" : "of all branches"}
  ⬢[acme@toolbox perf]$
Signed-off-by: default avatarClaire Jensen <cjense@google.com>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alyssa Ross <hi@alyssa.is>
Cc: Claire Jensen <clairej735@gmail.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Like Xu <likexu@tencent.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Link: https://lore.kernel.org/r/20220805200105.2020995-2-irogers@google.comSigned-off-by: default avatarIan Rogers <irogers@google.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent eb555cb5
...@@ -570,6 +570,27 @@ Additional metrics may be printed with all earlier fields being empty. ...@@ -570,6 +570,27 @@ Additional metrics may be printed with all earlier fields being empty.
include::intel-hybrid.txt[] include::intel-hybrid.txt[]
JSON FORMAT
-----------
With -j, perf stat is able to print out a JSON format output
that can be used for parsing.
- timestamp : optional usec time stamp in fractions of second (with -I)
- optional aggregate options:
- core : core identifier (with --per-core)
- die : die identifier (with --per-die)
- socket : socket identifier (with --per-socket)
- node : node identifier (with --per-node)
- thread : thread identifier (with --per-thread)
- counter-value : counter value
- unit : unit of the counter value or empty
- event : event name
- variance : optional variance if multiple values are collected (with -r)
- runtime : run time of counter
- metric-value : optional metric value
- metric-unit : optional unit of metric
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-top[1], linkperf:perf-list[1] linkperf:perf-top[1], linkperf:perf-list[1]
...@@ -1250,6 +1250,8 @@ static struct option stat_options[] = { ...@@ -1250,6 +1250,8 @@ static struct option stat_options[] = {
"Merge identical named hybrid events"), "Merge identical named hybrid events"),
OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator", OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
"print counts with custom separator"), "print counts with custom separator"),
OPT_BOOLEAN('j', "json-output", &stat_config.json_output,
"print counts in JSON format"),
OPT_CALLBACK('G', "cgroup", &evsel_list, "name", OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
"monitor event in cgroup name only", parse_stat_cgroups), "monitor event in cgroup name only", parse_stat_cgroups),
OPT_STRING(0, "for-each-cgroup", &stat_config.cgroup_list, "name", OPT_STRING(0, "for-each-cgroup", &stat_config.cgroup_list, "name",
...@@ -1436,6 +1438,7 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode) ...@@ -1436,6 +1438,7 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
case AGGR_GLOBAL: case AGGR_GLOBAL:
case AGGR_THREAD: case AGGR_THREAD:
case AGGR_UNSET: case AGGR_UNSET:
case AGGR_MAX:
default: default:
return NULL; return NULL;
} }
...@@ -1460,6 +1463,7 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode) ...@@ -1460,6 +1463,7 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode)
case AGGR_GLOBAL: case AGGR_GLOBAL:
case AGGR_THREAD: case AGGR_THREAD:
case AGGR_UNSET: case AGGR_UNSET:
case AGGR_MAX:
default: default:
return NULL; return NULL;
} }
...@@ -1610,6 +1614,7 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode) ...@@ -1610,6 +1614,7 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode)
case AGGR_GLOBAL: case AGGR_GLOBAL:
case AGGR_THREAD: case AGGR_THREAD:
case AGGR_UNSET: case AGGR_UNSET:
case AGGR_MAX:
default: default:
return NULL; return NULL;
} }
...@@ -1630,6 +1635,7 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode) ...@@ -1630,6 +1635,7 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode)
case AGGR_GLOBAL: case AGGR_GLOBAL:
case AGGR_THREAD: case AGGR_THREAD:
case AGGR_UNSET: case AGGR_UNSET:
case AGGR_MAX:
default: default:
return NULL; return NULL;
} }
......
This diff is collapsed.
...@@ -401,6 +401,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, ...@@ -401,6 +401,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel,
aggr->ena += count->ena; aggr->ena += count->ena;
aggr->run += count->run; aggr->run += count->run;
case AGGR_UNSET: case AGGR_UNSET:
case AGGR_MAX:
default: default:
break; break;
} }
......
...@@ -57,6 +57,7 @@ enum aggr_mode { ...@@ -57,6 +57,7 @@ enum aggr_mode {
AGGR_THREAD, AGGR_THREAD,
AGGR_UNSET, AGGR_UNSET,
AGGR_NODE, AGGR_NODE,
AGGR_MAX
}; };
enum { enum {
...@@ -121,6 +122,7 @@ struct perf_stat_config { ...@@ -121,6 +122,7 @@ struct perf_stat_config {
bool no_inherit; bool no_inherit;
bool identifier; bool identifier;
bool csv_output; bool csv_output;
bool json_output;
bool interval_clear; bool interval_clear;
bool metric_only; bool metric_only;
bool null_run; bool null_run;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment