diff options
| author | Adrian Hunter <adrian.hunter@intel.com> | 2014-10-30 10:09:47 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-11-03 16:10:06 -0500 |
| commit | 6a70307ddcd9999598c399d55dc44c07816a575f (patch) | |
| tree | 210143ded656ebf0ebc3f828caa0ddf7c080a599 /tools/perf/scripts/python | |
| parent | 88f50d602f500d206f2f5a9a9751dd45f2d97739 (diff) | |
perf tools: Add call information to Python export
Add the ability to export detailed information about paired calls and
returns to Python db export and the export-to-postgresql.py script.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1414678188-14946-7-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/scripts/python')
| -rw-r--r-- | tools/perf/scripts/python/bin/export-to-postgresql-report | 15 | ||||
| -rw-r--r-- | tools/perf/scripts/python/export-to-postgresql.py | 66 |
2 files changed, 75 insertions, 6 deletions
diff --git a/tools/perf/scripts/python/bin/export-to-postgresql-report b/tools/perf/scripts/python/bin/export-to-postgresql-report index a8fdd15f85bf..cd335b6e2a01 100644 --- a/tools/perf/scripts/python/bin/export-to-postgresql-report +++ b/tools/perf/scripts/python/bin/export-to-postgresql-report | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: export perf data to a postgresql database | 2 | # description: export perf data to a postgresql database |
| 3 | # args: [database name] [columns] | 3 | # args: [database name] [columns] [calls] |
| 4 | n_args=0 | 4 | n_args=0 |
| 5 | for i in "$@" | 5 | for i in "$@" |
| 6 | do | 6 | do |
| @@ -9,11 +9,16 @@ do | |||
| 9 | fi | 9 | fi |
| 10 | n_args=$(( $n_args + 1 )) | 10 | n_args=$(( $n_args + 1 )) |
| 11 | done | 11 | done |
| 12 | if [ "$n_args" -gt 2 ] ; then | 12 | if [ "$n_args" -gt 3 ] ; then |
| 13 | echo "usage: export-to-postgresql-report [database name] [columns]" | 13 | echo "usage: export-to-postgresql-report [database name] [columns] [calls]" |
| 14 | exit | 14 | exit |
| 15 | fi | 15 | fi |
| 16 | if [ "$n_args" -gt 1 ] ; then | 16 | if [ "$n_args" -gt 2 ] ; then |
| 17 | dbname=$1 | ||
| 18 | columns=$2 | ||
| 19 | calls=$3 | ||
| 20 | shift 3 | ||
| 21 | elif [ "$n_args" -gt 1 ] ; then | ||
| 17 | dbname=$1 | 22 | dbname=$1 |
| 18 | columns=$2 | 23 | columns=$2 |
| 19 | shift 2 | 24 | shift 2 |
| @@ -21,4 +26,4 @@ elif [ "$n_args" -gt 0 ] ; then | |||
| 21 | dbname=$1 | 26 | dbname=$1 |
| 22 | shift | 27 | shift |
| 23 | fi | 28 | fi |
| 24 | perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/export-to-postgresql.py $dbname $columns | 29 | perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/export-to-postgresql.py $dbname $columns $calls |
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index bb79aecccf58..4cdafd880074 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py | |||
| @@ -40,10 +40,12 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | |||
| 40 | #from Core import * | 40 | #from Core import * |
| 41 | 41 | ||
| 42 | perf_db_export_mode = True | 42 | perf_db_export_mode = True |
| 43 | perf_db_export_calls = False | ||
| 43 | 44 | ||
| 44 | def usage(): | 45 | def usage(): |
| 45 | print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>]" | 46 | print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>]" |
| 46 | print >> sys.stderr, "where: columns 'all' or 'branches'" | 47 | print >> sys.stderr, "where: columns 'all' or 'branches'" |
| 48 | print >> sys.stderr, " calls 'calls' => create calls table" | ||
| 47 | raise Exception("Too few arguments") | 49 | raise Exception("Too few arguments") |
| 48 | 50 | ||
| 49 | if (len(sys.argv) < 2): | 51 | if (len(sys.argv) < 2): |
| @@ -61,6 +63,12 @@ if columns not in ("all", "branches"): | |||
| 61 | 63 | ||
| 62 | branches = (columns == "branches") | 64 | branches = (columns == "branches") |
| 63 | 65 | ||
| 66 | if (len(sys.argv) >= 4): | ||
| 67 | if (sys.argv[3] == "calls"): | ||
| 68 | perf_db_export_calls = True | ||
| 69 | else: | ||
| 70 | usage() | ||
| 71 | |||
| 64 | output_dir_name = os.getcwd() + "/" + dbname + "-perf-data" | 72 | output_dir_name = os.getcwd() + "/" + dbname + "-perf-data" |
| 65 | os.mkdir(output_dir_name) | 73 | os.mkdir(output_dir_name) |
| 66 | 74 | ||
| @@ -170,6 +178,25 @@ else: | |||
| 170 | 'branch_type integer,' | 178 | 'branch_type integer,' |
| 171 | 'in_tx boolean)') | 179 | 'in_tx boolean)') |
| 172 | 180 | ||
| 181 | if perf_db_export_calls: | ||
| 182 | do_query(query, 'CREATE TABLE call_paths (' | ||
| 183 | 'id bigint NOT NULL,' | ||
| 184 | 'parent_id bigint,' | ||
| 185 | 'symbol_id bigint,' | ||
| 186 | 'ip bigint)') | ||
| 187 | do_query(query, 'CREATE TABLE calls (' | ||
| 188 | 'id bigint NOT NULL,' | ||
| 189 | 'thread_id bigint,' | ||
| 190 | 'comm_id bigint,' | ||
| 191 | 'call_path_id bigint,' | ||
| 192 | 'call_time bigint,' | ||
| 193 | 'return_time bigint,' | ||
| 194 | 'branch_count bigint,' | ||
| 195 | 'call_id bigint,' | ||
| 196 | 'return_id bigint,' | ||
| 197 | 'parent_call_path_id bigint,' | ||
| 198 | 'flags integer)') | ||
| 199 | |||
| 173 | do_query(query, 'CREATE VIEW samples_view AS ' | 200 | do_query(query, 'CREATE VIEW samples_view AS ' |
| 174 | 'SELECT ' | 201 | 'SELECT ' |
| 175 | 'id,' | 202 | 'id,' |
| @@ -246,6 +273,9 @@ dso_file = open_output_file("dso_table.bin") | |||
| 246 | symbol_file = open_output_file("symbol_table.bin") | 273 | symbol_file = open_output_file("symbol_table.bin") |
| 247 | branch_type_file = open_output_file("branch_type_table.bin") | 274 | branch_type_file = open_output_file("branch_type_table.bin") |
| 248 | sample_file = open_output_file("sample_table.bin") | 275 | sample_file = open_output_file("sample_table.bin") |
| 276 | if perf_db_export_calls: | ||
| 277 | call_path_file = open_output_file("call_path_table.bin") | ||
| 278 | call_file = open_output_file("call_table.bin") | ||
| 249 | 279 | ||
| 250 | def trace_begin(): | 280 | def trace_begin(): |
| 251 | print datetime.datetime.today(), "Writing to intermediate files..." | 281 | print datetime.datetime.today(), "Writing to intermediate files..." |
| @@ -256,6 +286,9 @@ def trace_begin(): | |||
| 256 | comm_table(0, "unknown") | 286 | comm_table(0, "unknown") |
| 257 | dso_table(0, 0, "unknown", "unknown", "") | 287 | dso_table(0, 0, "unknown", "unknown", "") |
| 258 | symbol_table(0, 0, 0, 0, 0, "unknown") | 288 | symbol_table(0, 0, 0, 0, 0, "unknown") |
| 289 | sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | ||
| 290 | if perf_db_export_calls: | ||
| 291 | call_path_table(0, 0, 0, 0) | ||
| 259 | 292 | ||
| 260 | unhandled_count = 0 | 293 | unhandled_count = 0 |
| 261 | 294 | ||
| @@ -270,6 +303,9 @@ def trace_end(): | |||
| 270 | copy_output_file(symbol_file, "symbols") | 303 | copy_output_file(symbol_file, "symbols") |
| 271 | copy_output_file(branch_type_file, "branch_types") | 304 | copy_output_file(branch_type_file, "branch_types") |
| 272 | copy_output_file(sample_file, "samples") | 305 | copy_output_file(sample_file, "samples") |
| 306 | if perf_db_export_calls: | ||
| 307 | copy_output_file(call_path_file, "call_paths") | ||
| 308 | copy_output_file(call_file, "calls") | ||
| 273 | 309 | ||
| 274 | print datetime.datetime.today(), "Removing intermediate files..." | 310 | print datetime.datetime.today(), "Removing intermediate files..." |
| 275 | remove_output_file(evsel_file) | 311 | remove_output_file(evsel_file) |
| @@ -281,6 +317,9 @@ def trace_end(): | |||
| 281 | remove_output_file(symbol_file) | 317 | remove_output_file(symbol_file) |
| 282 | remove_output_file(branch_type_file) | 318 | remove_output_file(branch_type_file) |
| 283 | remove_output_file(sample_file) | 319 | remove_output_file(sample_file) |
| 320 | if perf_db_export_calls: | ||
| 321 | remove_output_file(call_path_file) | ||
| 322 | remove_output_file(call_file) | ||
| 284 | os.rmdir(output_dir_name) | 323 | os.rmdir(output_dir_name) |
| 285 | print datetime.datetime.today(), "Adding primary keys" | 324 | print datetime.datetime.today(), "Adding primary keys" |
| 286 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') | 325 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') |
| @@ -292,6 +331,9 @@ def trace_end(): | |||
| 292 | do_query(query, 'ALTER TABLE symbols ADD PRIMARY KEY (id)') | 331 | do_query(query, 'ALTER TABLE symbols ADD PRIMARY KEY (id)') |
| 293 | do_query(query, 'ALTER TABLE branch_types ADD PRIMARY KEY (id)') | 332 | do_query(query, 'ALTER TABLE branch_types ADD PRIMARY KEY (id)') |
| 294 | do_query(query, 'ALTER TABLE samples ADD PRIMARY KEY (id)') | 333 | do_query(query, 'ALTER TABLE samples ADD PRIMARY KEY (id)') |
| 334 | if perf_db_export_calls: | ||
| 335 | do_query(query, 'ALTER TABLE call_paths ADD PRIMARY KEY (id)') | ||
| 336 | do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)') | ||
| 295 | 337 | ||
| 296 | print datetime.datetime.today(), "Adding foreign keys" | 338 | print datetime.datetime.today(), "Adding foreign keys" |
| 297 | do_query(query, 'ALTER TABLE threads ' | 339 | do_query(query, 'ALTER TABLE threads ' |
| @@ -313,6 +355,18 @@ def trace_end(): | |||
| 313 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id),' | 355 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id),' |
| 314 | 'ADD CONSTRAINT todsofk FOREIGN KEY (to_dso_id) REFERENCES dsos (id),' | 356 | 'ADD CONSTRAINT todsofk FOREIGN KEY (to_dso_id) REFERENCES dsos (id),' |
| 315 | 'ADD CONSTRAINT tosymbolfk FOREIGN KEY (to_symbol_id) REFERENCES symbols (id)') | 357 | 'ADD CONSTRAINT tosymbolfk FOREIGN KEY (to_symbol_id) REFERENCES symbols (id)') |
| 358 | if perf_db_export_calls: | ||
| 359 | do_query(query, 'ALTER TABLE call_paths ' | ||
| 360 | 'ADD CONSTRAINT parentfk FOREIGN KEY (parent_id) REFERENCES call_paths (id),' | ||
| 361 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id)') | ||
| 362 | do_query(query, 'ALTER TABLE calls ' | ||
| 363 | 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id),' | ||
| 364 | 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),' | ||
| 365 | 'ADD CONSTRAINT call_pathfk FOREIGN KEY (call_path_id) REFERENCES call_paths (id),' | ||
| 366 | 'ADD CONSTRAINT callfk FOREIGN KEY (call_id) REFERENCES samples (id),' | ||
| 367 | 'ADD CONSTRAINT returnfk FOREIGN KEY (return_id) REFERENCES samples (id),' | ||
| 368 | 'ADD CONSTRAINT parent_call_pathfk FOREIGN KEY (parent_call_path_id) REFERENCES call_paths (id)') | ||
| 369 | do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') | ||
| 316 | 370 | ||
| 317 | if (unhandled_count): | 371 | if (unhandled_count): |
| 318 | print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" | 372 | print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" |
| @@ -378,3 +432,13 @@ def sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, sy | |||
| 378 | else: | 432 | else: |
| 379 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiqiiiB", 21, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 8, period, 8, weight, 8, transaction, 8, data_src, 4, branch_type, 1, in_tx) | 433 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiqiiiB", 21, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 8, period, 8, weight, 8, transaction, 8, data_src, 4, branch_type, 1, in_tx) |
| 380 | sample_file.write(value) | 434 | sample_file.write(value) |
| 435 | |||
| 436 | def call_path_table(cp_id, parent_id, symbol_id, ip, *x): | ||
| 437 | fmt = "!hiqiqiqiq" | ||
| 438 | value = struct.pack(fmt, 4, 8, cp_id, 8, parent_id, 8, symbol_id, 8, ip) | ||
| 439 | call_path_file.write(value) | ||
| 440 | |||
| 441 | def call_return_table(cr_id, thread_id, comm_id, call_path_id, call_time, return_time, branch_count, call_id, return_id, parent_call_path_id, flags, *x): | ||
| 442 | fmt = "!hiqiqiqiqiqiqiqiqiqiqii" | ||
| 443 | value = struct.pack(fmt, 11, 8, cr_id, 8, thread_id, 8, comm_id, 8, call_path_id, 8, call_time, 8, return_time, 8, branch_count, 8, call_id, 8, return_id, 8, parent_call_path_id, 4, flags) | ||
| 444 | call_file.write(value) | ||
