aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/python/export-to-postgresql.py
diff options
context:
space:
mode:
authorTony Jones <tonyj@suse.de>2019-03-08 19:05:16 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-03-11 15:12:57 -0400
commit1937b0560c3ea43b1b0f7d3617949ca50de8f8c0 (patch)
tree62fad5e7e0ed89b3de938393e39cc48443e2b5f0 /tools/perf/scripts/python/export-to-postgresql.py
parentbeda0e725e5f06aca27eda2434ea9447dad88e36 (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.py58
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
13from __future__ import print_function
14
13import os 15import os
14import sys 16import sys
15import struct 17import struct
@@ -199,6 +201,18 @@ import datetime
199 201
200from PySide.QtSql import * 202from PySide.QtSql import *
201 203
204if sys.version_info < (3, 0):
205 def toserverstr(str):
206 return str
207 def toclientstr(str):
208 return str
209else:
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
203from ctypes import * 217from ctypes import *
204libpq = CDLL("libpq.so.5") 218libpq = CDLL("libpq.so.5")
@@ -234,12 +248,14 @@ perf_db_export_mode = True
234perf_db_export_calls = False 248perf_db_export_calls = False
235perf_db_export_callchains = False 249perf_db_export_callchains = False
236 250
251def printerr(*args, **kw_args):
252 print(*args, file=sys.stderr, **kw_args)
237 253
238def usage(): 254def 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
245if (len(sys.argv) < 2): 261if (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
276print datetime.datetime.today(), "Creating database..." 292print(datetime.datetime.today(), "Creating database...")
277 293
278db = QSqlDatabase.addDatabase('QPSQL') 294db = QSqlDatabase.addDatabase('QPSQL')
279query = QSqlQuery(db) 295query = QSqlQuery(db)
@@ -506,12 +522,12 @@ do_query(query, 'CREATE VIEW samples_view AS '
506 ' FROM samples') 522 ' FROM samples')
507 523
508 524
509file_header = struct.pack("!11sii", "PGCOPY\n\377\r\n\0", 0, 0) 525file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0)
510file_trailer = "\377\377" 526file_trailer = b"\377\377"
511 527
512def open_output_file(file_name): 528def 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
528def copy_output_file(file, table_name): 544def 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
568def trace_begin(): 584def 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():
582unhandled_count = 0 598unhandled_count = 0
583 599
584def trace_end(): 600def 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
669def trace_unhandled(event_name, context, event_fields_dict): 685def 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
676def evsel_table(evsel_id, evsel_name, *x): 692def 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
682def machine_table(machine_id, pid, root_dir, *x): 699def 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
692def comm_table(comm_id, comm_str, *x): 710def 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
703def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x): 722def 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
711def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x): 733def 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
717def branch_type_table(branch_type, name, *x): 740def 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)