diff options
author | Tony Jones <tonyj@suse.de> | 2019-03-08 19:05:16 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-03-11 15:12:57 -0400 |
commit | 1937b0560c3ea43b1b0f7d3617949ca50de8f8c0 (patch) | |
tree | 62fad5e7e0ed89b3de938393e39cc48443e2b5f0 /tools/perf/scripts/python/export-to-postgresql.py | |
parent | beda0e725e5f06aca27eda2434ea9447dad88e36 (diff) |
perf script python: Add Python3 support to export-to-postgresql.py
Support both Python2 and Python3 in the export-to-postgresql.py script.
The use of 'from __future__' implies the minimum supported Python2 version
is now v2.6
Signed-off-by: Tony Jones <tonyj@suse.de>
Link: http://lkml.kernel.org/r/20190309000518.2438-3-tonyj@suse.de
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/scripts/python/export-to-postgresql.py')
-rw-r--r-- | tools/perf/scripts/python/export-to-postgresql.py | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index 390a351d15ea..00ab972a2eba 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py | |||
@@ -10,6 +10,8 @@ | |||
10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
11 | # more details. | 11 | # more details. |
12 | 12 | ||
13 | from __future__ import print_function | ||
14 | |||
13 | import os | 15 | import os |
14 | import sys | 16 | import sys |
15 | import struct | 17 | import struct |
@@ -199,6 +201,18 @@ import datetime | |||
199 | 201 | ||
200 | from PySide.QtSql import * | 202 | from PySide.QtSql import * |
201 | 203 | ||
204 | if sys.version_info < (3, 0): | ||
205 | def toserverstr(str): | ||
206 | return str | ||
207 | def toclientstr(str): | ||
208 | return str | ||
209 | else: | ||
210 | # Assume UTF-8 server_encoding and client_encoding | ||
211 | def toserverstr(str): | ||
212 | return bytes(str, "UTF_8") | ||
213 | def toclientstr(str): | ||
214 | return bytes(str, "UTF_8") | ||
215 | |||
202 | # Need to access PostgreSQL C library directly to use COPY FROM STDIN | 216 | # Need to access PostgreSQL C library directly to use COPY FROM STDIN |
203 | from ctypes import * | 217 | from ctypes import * |
204 | libpq = CDLL("libpq.so.5") | 218 | libpq = CDLL("libpq.so.5") |
@@ -234,12 +248,14 @@ perf_db_export_mode = True | |||
234 | perf_db_export_calls = False | 248 | perf_db_export_calls = False |
235 | perf_db_export_callchains = False | 249 | perf_db_export_callchains = False |
236 | 250 | ||
251 | def printerr(*args, **kw_args): | ||
252 | print(*args, file=sys.stderr, **kw_args) | ||
237 | 253 | ||
238 | def usage(): | 254 | def usage(): |
239 | print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]" | 255 | printerr("Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]") |
240 | print >> sys.stderr, "where: columns 'all' or 'branches'" | 256 | printerr("where: columns 'all' or 'branches'") |
241 | print >> sys.stderr, " calls 'calls' => create calls and call_paths table" | 257 | printerr(" calls 'calls' => create calls and call_paths table") |
242 | print >> sys.stderr, " callchains 'callchains' => create call_paths table" | 258 | printerr(" callchains 'callchains' => create call_paths table") |
243 | raise Exception("Too few arguments") | 259 | raise Exception("Too few arguments") |
244 | 260 | ||
245 | if (len(sys.argv) < 2): | 261 | if (len(sys.argv) < 2): |
@@ -273,7 +289,7 @@ def do_query(q, s): | |||
273 | return | 289 | return |
274 | raise Exception("Query failed: " + q.lastError().text()) | 290 | raise Exception("Query failed: " + q.lastError().text()) |
275 | 291 | ||
276 | print datetime.datetime.today(), "Creating database..." | 292 | print(datetime.datetime.today(), "Creating database...") |
277 | 293 | ||
278 | db = QSqlDatabase.addDatabase('QPSQL') | 294 | db = QSqlDatabase.addDatabase('QPSQL') |
279 | query = QSqlQuery(db) | 295 | query = QSqlQuery(db) |
@@ -506,12 +522,12 @@ do_query(query, 'CREATE VIEW samples_view AS ' | |||
506 | ' FROM samples') | 522 | ' FROM samples') |
507 | 523 | ||
508 | 524 | ||
509 | file_header = struct.pack("!11sii", "PGCOPY\n\377\r\n\0", 0, 0) | 525 | file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0) |
510 | file_trailer = "\377\377" | 526 | file_trailer = b"\377\377" |
511 | 527 | ||
512 | def open_output_file(file_name): | 528 | def open_output_file(file_name): |
513 | path_name = output_dir_name + "/" + file_name | 529 | path_name = output_dir_name + "/" + file_name |
514 | file = open(path_name, "w+") | 530 | file = open(path_name, "wb+") |
515 | file.write(file_header) | 531 | file.write(file_header) |
516 | return file | 532 | return file |
517 | 533 | ||
@@ -526,13 +542,13 @@ def copy_output_file_direct(file, table_name): | |||
526 | 542 | ||
527 | # Use COPY FROM STDIN because security may prevent postgres from accessing the files directly | 543 | # Use COPY FROM STDIN because security may prevent postgres from accessing the files directly |
528 | def copy_output_file(file, table_name): | 544 | def copy_output_file(file, table_name): |
529 | conn = PQconnectdb("dbname = " + dbname) | 545 | conn = PQconnectdb(toclientstr("dbname = " + dbname)) |
530 | if (PQstatus(conn)): | 546 | if (PQstatus(conn)): |
531 | raise Exception("COPY FROM STDIN PQconnectdb failed") | 547 | raise Exception("COPY FROM STDIN PQconnectdb failed") |
532 | file.write(file_trailer) | 548 | file.write(file_trailer) |
533 | file.seek(0) | 549 | file.seek(0) |
534 | sql = "COPY " + table_name + " FROM STDIN (FORMAT 'binary')" | 550 | sql = "COPY " + table_name + " FROM STDIN (FORMAT 'binary')" |
535 | res = PQexec(conn, sql) | 551 | res = PQexec(conn, toclientstr(sql)) |
536 | if (PQresultStatus(res) != 4): | 552 | if (PQresultStatus(res) != 4): |
537 | raise Exception("COPY FROM STDIN PQexec failed") | 553 | raise Exception("COPY FROM STDIN PQexec failed") |
538 | data = file.read(65536) | 554 | data = file.read(65536) |
@@ -566,7 +582,7 @@ if perf_db_export_calls: | |||
566 | call_file = open_output_file("call_table.bin") | 582 | call_file = open_output_file("call_table.bin") |
567 | 583 | ||
568 | def trace_begin(): | 584 | def trace_begin(): |
569 | print datetime.datetime.today(), "Writing to intermediate files..." | 585 | print(datetime.datetime.today(), "Writing to intermediate files...") |
570 | # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs | 586 | # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs |
571 | evsel_table(0, "unknown") | 587 | evsel_table(0, "unknown") |
572 | machine_table(0, 0, "unknown") | 588 | machine_table(0, 0, "unknown") |
@@ -582,7 +598,7 @@ def trace_begin(): | |||
582 | unhandled_count = 0 | 598 | unhandled_count = 0 |
583 | 599 | ||
584 | def trace_end(): | 600 | def trace_end(): |
585 | print datetime.datetime.today(), "Copying to database..." | 601 | print(datetime.datetime.today(), "Copying to database...") |
586 | copy_output_file(evsel_file, "selected_events") | 602 | copy_output_file(evsel_file, "selected_events") |
587 | copy_output_file(machine_file, "machines") | 603 | copy_output_file(machine_file, "machines") |
588 | copy_output_file(thread_file, "threads") | 604 | copy_output_file(thread_file, "threads") |
@@ -597,7 +613,7 @@ def trace_end(): | |||
597 | if perf_db_export_calls: | 613 | if perf_db_export_calls: |
598 | copy_output_file(call_file, "calls") | 614 | copy_output_file(call_file, "calls") |
599 | 615 | ||
600 | print datetime.datetime.today(), "Removing intermediate files..." | 616 | print(datetime.datetime.today(), "Removing intermediate files...") |
601 | remove_output_file(evsel_file) | 617 | remove_output_file(evsel_file) |
602 | remove_output_file(machine_file) | 618 | remove_output_file(machine_file) |
603 | remove_output_file(thread_file) | 619 | remove_output_file(thread_file) |
@@ -612,7 +628,7 @@ def trace_end(): | |||
612 | if perf_db_export_calls: | 628 | if perf_db_export_calls: |
613 | remove_output_file(call_file) | 629 | remove_output_file(call_file) |
614 | os.rmdir(output_dir_name) | 630 | os.rmdir(output_dir_name) |
615 | print datetime.datetime.today(), "Adding primary keys" | 631 | print(datetime.datetime.today(), "Adding primary keys") |
616 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') | 632 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') |
617 | do_query(query, 'ALTER TABLE machines ADD PRIMARY KEY (id)') | 633 | do_query(query, 'ALTER TABLE machines ADD PRIMARY KEY (id)') |
618 | do_query(query, 'ALTER TABLE threads ADD PRIMARY KEY (id)') | 634 | do_query(query, 'ALTER TABLE threads ADD PRIMARY KEY (id)') |
@@ -627,7 +643,7 @@ def trace_end(): | |||
627 | if perf_db_export_calls: | 643 | if perf_db_export_calls: |
628 | do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)') | 644 | do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)') |
629 | 645 | ||
630 | print datetime.datetime.today(), "Adding foreign keys" | 646 | print(datetime.datetime.today(), "Adding foreign keys") |
631 | do_query(query, 'ALTER TABLE threads ' | 647 | do_query(query, 'ALTER TABLE threads ' |
632 | 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' | 648 | 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' |
633 | 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') | 649 | 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') |
@@ -663,8 +679,8 @@ def trace_end(): | |||
663 | do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') | 679 | do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') |
664 | 680 | ||
665 | if (unhandled_count): | 681 | if (unhandled_count): |
666 | print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" | 682 | print(datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events") |
667 | print datetime.datetime.today(), "Done" | 683 | print(datetime.datetime.today(), "Done") |
668 | 684 | ||
669 | def trace_unhandled(event_name, context, event_fields_dict): | 685 | def trace_unhandled(event_name, context, event_fields_dict): |
670 | global unhandled_count | 686 | global unhandled_count |
@@ -674,12 +690,14 @@ def sched__sched_switch(*x): | |||
674 | pass | 690 | pass |
675 | 691 | ||
676 | def evsel_table(evsel_id, evsel_name, *x): | 692 | def evsel_table(evsel_id, evsel_name, *x): |
693 | evsel_name = toserverstr(evsel_name) | ||
677 | n = len(evsel_name) | 694 | n = len(evsel_name) |
678 | fmt = "!hiqi" + str(n) + "s" | 695 | fmt = "!hiqi" + str(n) + "s" |
679 | value = struct.pack(fmt, 2, 8, evsel_id, n, evsel_name) | 696 | value = struct.pack(fmt, 2, 8, evsel_id, n, evsel_name) |
680 | evsel_file.write(value) | 697 | evsel_file.write(value) |
681 | 698 | ||
682 | def machine_table(machine_id, pid, root_dir, *x): | 699 | def machine_table(machine_id, pid, root_dir, *x): |
700 | root_dir = toserverstr(root_dir) | ||
683 | n = len(root_dir) | 701 | n = len(root_dir) |
684 | fmt = "!hiqiii" + str(n) + "s" | 702 | fmt = "!hiqiii" + str(n) + "s" |
685 | value = struct.pack(fmt, 3, 8, machine_id, 4, pid, n, root_dir) | 703 | value = struct.pack(fmt, 3, 8, machine_id, 4, pid, n, root_dir) |
@@ -690,6 +708,7 @@ def thread_table(thread_id, machine_id, process_id, pid, tid, *x): | |||
690 | thread_file.write(value) | 708 | thread_file.write(value) |
691 | 709 | ||
692 | def comm_table(comm_id, comm_str, *x): | 710 | def comm_table(comm_id, comm_str, *x): |
711 | comm_str = toserverstr(comm_str) | ||
693 | n = len(comm_str) | 712 | n = len(comm_str) |
694 | fmt = "!hiqi" + str(n) + "s" | 713 | fmt = "!hiqi" + str(n) + "s" |
695 | value = struct.pack(fmt, 2, 8, comm_id, n, comm_str) | 714 | value = struct.pack(fmt, 2, 8, comm_id, n, comm_str) |
@@ -701,6 +720,9 @@ def comm_thread_table(comm_thread_id, comm_id, thread_id, *x): | |||
701 | comm_thread_file.write(value) | 720 | comm_thread_file.write(value) |
702 | 721 | ||
703 | def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x): | 722 | def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x): |
723 | short_name = toserverstr(short_name) | ||
724 | long_name = toserverstr(long_name) | ||
725 | build_id = toserverstr(build_id) | ||
704 | n1 = len(short_name) | 726 | n1 = len(short_name) |
705 | n2 = len(long_name) | 727 | n2 = len(long_name) |
706 | n3 = len(build_id) | 728 | n3 = len(build_id) |
@@ -709,12 +731,14 @@ def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x): | |||
709 | dso_file.write(value) | 731 | dso_file.write(value) |
710 | 732 | ||
711 | def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x): | 733 | def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x): |
734 | symbol_name = toserverstr(symbol_name) | ||
712 | n = len(symbol_name) | 735 | n = len(symbol_name) |
713 | fmt = "!hiqiqiqiqiii" + str(n) + "s" | 736 | fmt = "!hiqiqiqiqiii" + str(n) + "s" |
714 | value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name) | 737 | value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name) |
715 | symbol_file.write(value) | 738 | symbol_file.write(value) |
716 | 739 | ||
717 | def branch_type_table(branch_type, name, *x): | 740 | def branch_type_table(branch_type, name, *x): |
741 | name = toserverstr(name) | ||
718 | n = len(name) | 742 | n = len(name) |
719 | fmt = "!hiii" + str(n) + "s" | 743 | fmt = "!hiii" + str(n) + "s" |
720 | value = struct.pack(fmt, 2, 4, branch_type, n, name) | 744 | value = struct.pack(fmt, 2, 4, branch_type, n, name) |