diff options
Diffstat (limited to 'tools/perf/util/data-convert-json.c')
| -rw-r--r-- | tools/perf/util/data-convert-json.c | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c index d9f805bf6fb0..d526c91312ed 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -25,6 +25,7 @@ #include "util/session.h" #include "util/symbol.h" #include "util/thread.h" +#include "util/time-utils.h" #include "util/tool.h" #ifdef HAVE_LIBTRACEEVENT @@ -35,13 +36,21 @@ struct convert_json { struct perf_tool tool; FILE *out; bool first; + struct perf_time_interval *ptime_range; + int range_size; + int range_num; + u64 events_count; + u64 skipped; }; // Outputs a JSON-encoded string surrounded by quotes with characters escaped. static void output_json_string(FILE *out, const char *s) { fputc('"', out); + if (!s) + goto out; + while (*s) { switch (*s) { @@ -65,6 +74,7 @@ static void output_json_string(FILE *out, const char *s) ++s; } +out: fputc('"', out); } @@ -165,6 +175,11 @@ static int process_sample_event(const struct perf_tool *tool, return -1; } + if (perf_time__ranges_skip_sample(c->ptime_range, c->range_num, sample->time)) { + ++c->skipped; + return 0; + } + ++c->events_count; if (c->first) @@ -257,7 +272,8 @@ static int process_sample_event(const struct perf_tool *tool, static void output_headers(struct perf_session *session, struct convert_json *c) { struct stat st; - struct perf_header *header = &session->header; + const struct perf_header *header = &session->header; + const struct perf_env *env = perf_session__env(session); int ret; int fd = perf_data__fd(session->data); int i; @@ -280,37 +296,37 @@ static void output_headers(struct perf_session *session, struct convert_json *c) output_json_key_format(out, true, 2, "data-size", "%" PRIu64, header->data_size); output_json_key_format(out, true, 2, "feat-offset", "%" PRIu64, header->feat_offset); - output_json_key_string(out, true, 2, "hostname", header->env.hostname); - output_json_key_string(out, true, 2, "os-release", header->env.os_release); - output_json_key_string(out, true, 2, "arch", header->env.arch); + output_json_key_string(out, true, 2, "hostname", env->hostname); + output_json_key_string(out, true, 2, "os-release", env->os_release); + output_json_key_string(out, true, 2, "arch", env->arch); - if (header->env.cpu_desc) - output_json_key_string(out, true, 2, "cpu-desc", header->env.cpu_desc); + if (env->cpu_desc) + output_json_key_string(out, true, 2, "cpu-desc", env->cpu_desc); - output_json_key_string(out, true, 2, "cpuid", header->env.cpuid); - output_json_key_format(out, true, 2, "nrcpus-online", "%u", header->env.nr_cpus_online); - output_json_key_format(out, true, 2, "nrcpus-avail", "%u", header->env.nr_cpus_avail); + output_json_key_string(out, true, 2, "cpuid", env->cpuid); + output_json_key_format(out, true, 2, "nrcpus-online", "%u", env->nr_cpus_online); + output_json_key_format(out, true, 2, "nrcpus-avail", "%u", env->nr_cpus_avail); - if (header->env.clock.enabled) { + if (env->clock.enabled) { output_json_key_format(out, true, 2, "clockid", - "%u", header->env.clock.clockid); + "%u", env->clock.clockid); output_json_key_format(out, true, 2, "clock-time", - "%" PRIu64, header->env.clock.clockid_ns); + "%" PRIu64, env->clock.clockid_ns); output_json_key_format(out, true, 2, "real-time", - "%" PRIu64, header->env.clock.tod_ns); + "%" PRIu64, env->clock.tod_ns); } - output_json_key_string(out, true, 2, "perf-version", header->env.version); + output_json_key_string(out, true, 2, "perf-version", env->version); output_json_key_format(out, true, 2, "cmdline", "["); - for (i = 0; i < header->env.nr_cmdline; i++) { + for (i = 0; i < env->nr_cmdline; i++) { output_json_delimiters(out, i != 0, 3); - output_json_string(c->out, header->env.cmdline_argv[i]); + output_json_string(c->out, env->cmdline_argv[i]); } output_json_format(out, false, 2, "]"); } -int bt_convert__perf2json(const char *input_name, const char *output_name, +int bt_convert__perf2json(const char *_input_name, const char *output_name, struct perf_data_convert_opts *opts __maybe_unused) { struct perf_session *session; @@ -319,10 +335,14 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, struct convert_json c = { .first = true, .events_count = 0, + .ptime_range = NULL, + .range_size = 0, + .range_num = 0, + .skipped = 0, }; struct perf_data data = { .mode = PERF_DATA_MODE_READ, - .path = input_name, + .path = _input_name, .force = opts->force, }; @@ -344,6 +364,8 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, c.tool.auxtrace_info = perf_event__process_auxtrace_info; c.tool.auxtrace = perf_event__process_auxtrace; c.tool.event_update = perf_event__process_event_update; + c.tool.attr = perf_event__process_attr; + c.tool.feature = perf_event__process_feature; c.tool.ordering_requires_timestamps = true; if (opts->all) { @@ -376,12 +398,20 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, fprintf(stderr, "Error creating perf session!\n"); goto err_fclose; } - - if (symbol__init(&session->header.env) < 0) { + if (symbol__init(perf_session__env(session)) < 0) { fprintf(stderr, "Symbol init error!\n"); goto err_session_delete; } + if (opts->time_str) { + ret = perf_time__parse_for_ranges(opts->time_str, session, + &c.ptime_range, + &c.range_size, + &c.range_num); + if (ret < 0) + goto err_session_delete; + } + // The opening brace is printed manually because it isn't delimited from a // previous value (i.e. we don't want a leading newline) fputc('{', c.out); @@ -403,15 +433,23 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, output_json_format(c.out, false, 0, "}"); fputc('\n', c.out); - fprintf(stderr, - "[ perf data convert: Converted '%s' into JSON data '%s' ]\n", - data.path, output_name); + fprintf(stderr, "[ perf data convert: Converted '%s' into JSON data '%s' ]\n", + data.path, output_name); fprintf(stderr, - "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n", - (ftell(c.out)) / 1024.0 / 1024.0, c.events_count); + "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n", + (ftell(c.out)) / 1024.0 / 1024.0, c.events_count); + + if (c.skipped) { + fprintf(stderr, "[ perf data convert: Skipped %" PRIu64 " samples ]\n", + c.skipped); + } ret = 0; + + if (c.ptime_range) + zfree(&c.ptime_range); + err_session_delete: perf_session__delete(session); err_fclose: |
