• Nicholas Fraser's avatar
    perf data: Add JSON export · d0713d4c
    Nicholas Fraser authored
    This adds a feature to export perf data to JSON.
    
    The resolved symbols are exported into the JSON so that external tools
    don't need to load the dsos themselves (or even have access to them at
    all.) This makes it easy to load and analyze perf data with standalone
    tools where direct perf or libbabeltrace integration is impractical.
    
    The exporter uses a minimal inline JSON encoding without any external
    dependencies. Currently it only outputs some headers and sample metadata
    but it's easily extensible.
    
    Use it like this:
    
      $ perf data convert --to-json out.json
    
    Committer notes:
    
    Fixup a __printf() bug that broke the build:
    
      util/data-convert-json.c:103:11: error: expected ‘)’ before numeric constant
        103 | __(printf, 5, 6)
            |           ^~
            |           )
      util/data-convert-json.c: In function ‘output_sample_callchain_entry’:
      util/data-convert-json.c:124:2: error: implicit declaration of function ‘output_json_key_format’; did you mean ‘output_json_format’? [-Werror=implicit-function-declaration]
        124 |  output_json_key_format(out, false, 5, "ip", "\"0x%" PRIx64 "\"", ip);
            |  ^~~~~~~~~~~~~~~~~~~~~~
            |  output_json_format
    
    Also had to add this patch to fix errors reported by various versions of
    clang:
    
      -       if (al && al->sym && al->sym->name && strlen(al->sym->name) > 0) {
      +       if (al && al->sym && al->sym->namelen) {
    
    al->sym->name is a zero sized array, to avoid one extra alloc in the
    symbol__new() constructor, sym->namelen carries its strlen.
    
    Committer testing:
    
      $ ls -la out.json
      ls: cannot access 'out.json': No such file or directory
      $ perf record sleep 0.1
      [ perf record: Woken up 1 times to write data ]
      [ perf record: Captured and wrote 0.001 MB perf.data (8 samples) ]
      $ perf report --stats | grep -w SAMPLE
                SAMPLE events:          8
      $ perf data convert --to-json out.json
      [ perf data convert: Converted 'perf.data' into JSON data 'out.json' ]
      [ perf data convert: Converted and wrote 0.002 MB (8 samples) ]
      $ ls -la out.json
      -rw-rw-r--. 1 acme acme 2017 Apr 26 17:29 out.json
      $ cat out.json
      {
      	"linux-perf-json-version": 1,
      	"headers": {
      		"header-version": 1,
      		"captured-on": "2021-04-26T20:28:57Z",
      		"data-offset": 432,
      		"data-size": 1016,
      		"feat-offset": 1448,
      		"hostname": "five",
      		"os-release": "5.11.14-200.fc33.x86_64",
      		"arch": "x86_64",
      		"cpu-desc": "AMD Ryzen 9 3900X 12-Core Processor",
      		"cpuid": "AuthenticAMD,23,113,0",
      		"nrcpus-online": 24,
      		"nrcpus-avail": 24,
      		"perf-version": "5.12.gee134f3189bd",
      		"cmdline": [
      			"/home/acme/bin/perf",
      			"record",
      			"sleep",
      			"0.1"
      		]
      	},
      	"samples": [
      		{
      			"timestamp": 170517539043684,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0xffffffffa6268827"
      				}
      			]
      		},
      		{
      			"timestamp": 170517539048443,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0xffffffffa661359d"
      				}
      			]
      		},
      		{
      			"timestamp": 170517539051018,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0xffffffffa6311e18"
      				}
      			]
      		},
      		{
      			"timestamp": 170517539053652,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0x7fdb77b4812b",
      					"symbol": "_dl_start",
      					"dso": "ld-2.32.so"
      				}
      			]
      		},
      		{
      			"timestamp": 170517539055306,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0xffffffffa6269286"
      				}
      			]
      		},
      		{
      			"timestamp": 170517539057590,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0xffffffffa62abd8b"
      				}
      			]
      		},
      		{
      			"timestamp": 170517539067559,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0x7fdb77b5e9e9",
      					"symbol": "__GI___tunables_init",
      					"dso": "ld-2.32.so"
      				}
      			]
      		},
      		{
      			"timestamp": 170517539282452,
      			"pid": 375844,
      			"tid": 375844,
      			"comm": "sleep",
      			"callchain": [
      				{
      					"ip": "0x7fdb779978d2",
      					"symbol": "getenv",
      					"dso": "libc-2.32.so"
      				}
      			]
      		}
      	]
      }
      $
    Signed-off-by: default avatarNicholas Fraser <nfraser@codeweavers.com>
    Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Changbin Du <changbin.du@intel.com>
    Cc: Ian Rogers <irogers@google.com>
    Cc: Jin Yao <yao.jin@linux.intel.com>
    Cc: Jiri Olsa <jolsa@redhat.com>
    Cc: Kan Liang <kan.liang@linux.intel.com>
    Cc: Mark Rutland <mark.rutland@arm.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Tan Xiaojun <tanxiaojun@huawei.com>
    Cc: Ulrich Czekalla <uczekalla@codeweavers.com>
    Link: http://lore.kernel.org/lkml/3884969f-804d-2f53-c648-e2b0bd85edff@codeweavers.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    d0713d4c
builtin-data.c 3.15 KB