# export-to-postgresql.py: export perf data to a postgresql database# Copyright (c) 2014, Intel Corporation.## This program is free software; you can redistribute it and/or modify it# under the terms and conditions of the GNU General Public License,# version 2, as published by the Free Software Foundation.## This program is distributed in the hope it will be useful, but WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for# more details. from __future__ import print_function import osimport sysimport structimport datetime # To use this script you will need to have installed package python-pyside which# provides LGPL-licensed Python bindings for Qt. You will also need the package# libqt4-sql-psql for Qt postgresql support.## The script assumes postgresql is running on the local machine and that the# user has postgresql permissions to create databases. Examples of installing# postgresql and adding such a user are:## fedora:## $ sudo yum install postgresql postgresql-server qt-postgresql# $ sudo su - postgres -c initdb# $ sudo service postgresql start# $ sudo su - postgres# $ createuser -s <your user id here> # Older versions may not support -s, in which case answer the prompt below:# Shall the new role be a superuser? (y/n) y# $ sudo yum install python-pyside## Alternately, to use Python3 and/or pyside 2, one of the following:# $ sudo yum install python3-pyside# $ pip install --user PySide2# $ pip3 install --user PySide2## ubuntu:## $ sudo apt-get install postgresql# $ sudo su - postgres# $ createuser -s <your user id here># $ sudo apt-get install python-pyside.qtsql libqt4-sql-psql## Alternately, to use Python3 and/or pyside 2, one of the following:## $ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql# $ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql# $ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql## An example of using this script with Intel PT:## $ perf record -e intel_pt//u ls# $ perf script -s ~/libexec/perf-core/scripts/python/export-to-postgresql.py pt_example branches calls# 2015-05-29 12:49:23.464364 Creating database...# 2015-05-29 12:49:26.281717 Writing to intermediate files...# 2015-05-29 12:49:27.190383 Copying to database...# 2015-05-29 12:49:28.140451 Removing intermediate files...# 2015-05-29 12:49:28.147451 Adding primary keys# 2015-05-29 12:49:28.655683 Adding foreign keys# 2015-05-29 12:49:29.365350 Done## To browse the database, psql can be used e.g.## $ psql pt_example# pt_example=# select * from samples_view where id < 100;# pt_example=# \d+# pt_example=# \d+ samples_view# pt_example=# \q## An example of using the database is provided by the script# exported-sql-viewer.py. Refer to that script for details.## Tables:## The tables largely correspond to perf tools' data structures. They are largely self-explanatory.## samples## 'samples' is the main table. It represents what instruction was executing at a point in time# when something (a selected event) happened. The memory address is the instruction pointer or 'ip'.## calls## 'calls' represents function calls and is related to 'samples' by 'call_id' and 'return_id'.# 'calls' is only created when the 'calls' option to this script is specified.## call_paths## 'call_paths' represents all the call stacks. Each 'call' has an associated record in 'call_paths'.# 'calls_paths' is only created when the 'calls' option to this script is specified.## branch_types## 'branch_types' provides descriptions for each type of branch.## comm_threads## 'comm_threads' shows how 'comms' relates to 'threads'.## comms## 'comms' contains a record for each 'comm' - the name given to the executable that is running.## dsos## 'dsos' contains a record for each executable file or library.## machines## 'machines' can be used to distinguish virtual machines if virtualization is supported.## selected_events## 'selected_events' contains a record for each kind of event that has been sampled.## symbols## 'symbols' contains a record for each symbol. Only symbols that have samples are present.## threads## 'threads' contains a record for each thread.## Views:## Most of the tables have views for more friendly display. The views are:## calls_view# call_paths_view# comm_threads_view# dsos_view# machines_view# samples_view# symbols_view# threads_view## More examples of browsing the database with psql:# Note that some of the examples are not the most optimal SQL query.# Note that call information is only available if the script's 'calls' option has been used.## Top 10 function calls (not aggregated by symbol):## SELECT * FROM calls_view ORDER BY elapsed_time DESC LIMIT 10;## Top 10 function calls (aggregated by symbol):## SELECT symbol_id,(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,# SUM(elapsed_time) AS tot_elapsed_time,SUM(branch_count) AS tot_branch_count# FROM calls_view GROUP BY symbol_id ORDER BY tot_elapsed_time DESC LIMIT 10;## Note that the branch count gives a rough estimation of cpu usage, so functions# that took a long time but have a relatively low branch count must have spent time# waiting.## Find symbols by pattern matching on part of the name (e.g. names containing 'alloc'):## SELECT * FROM symbols_view WHERE name LIKE '%alloc%';## Top 10 function calls for a specific symbol (e.g. whose symbol_id is 187):## SELECT * FROM calls_view WHERE symbol_id = 187 ORDER BY elapsed_time DESC LIMIT 10;## Show function calls made by function in the same context (i.e. same call path) (e.g. one with call_path_id 254):## SELECT * FROM calls_view WHERE parent_call_path_id = 254;## Show branches made during a function call (e.g. where call_id is 29357 and return_id is 29370 and tid is 29670)## SELECT * FROM samples_view WHERE id >= 29357 AND id <= 29370 AND tid = 29670 AND event LIKE 'branches%';## Show transactions:## SELECT * FROM samples_view WHERE event = 'transactions';## Note transaction start has 'in_tx' true whereas, transaction end has 'in_tx' false.# Transaction aborts have branch_type_name 'transaction abort'## Show transaction aborts:## SELECT * FROM samples_view WHERE event = 'transactions' AND branch_type_name = 'transaction abort';## To print a call stack requires walking the call_paths table. For example this python script:# #!/usr/bin/python2## import sys# from PySide.QtSql import *## if __name__ == '__main__':# if (len(sys.argv) < 3):# print >> sys.stderr, "Usage is: printcallstack.py <database name> <call_path_id>"# raise Exception("Too few arguments")# dbname = sys.argv[1]# call_path_id = sys.argv[2]# db = QSqlDatabase.addDatabase('QPSQL')# db.setDatabaseName(dbname)# if not db.open():# raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text())# query = QSqlQuery(db)# print " id ip symbol_id symbol dso_id dso_short_name"# while call_path_id != 0 and call_path_id != 1:# ret = query.exec_('SELECT * FROM call_paths_view WHERE id = ' + str(call_path_id))# if not ret:# raise Exception("Query failed: " + query.lastError().text())# if not query.next():# raise Exception("Query failed")# print "{0:>6} {1:>10} {2:>9} {3:<30} {4:>6} {5:<30}".format(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4), query.value(5))# call_path_id = query.value(6) pyside_version_1 = Trueif not "pyside-version-1" in sys.argv: try: from PySide2.QtSql import * pyside_version_1 = False except: pass if pyside_version_1: from PySide.QtSql import * if sys.version_info < (3, 0): def toserverstr(str): return str def toclientstr(str): return strelse: # Assume UTF-8 server_encoding and client_encoding def toserverstr(str): return bytes(str, "UTF_8") def toclientstr(str): return bytes(str, "UTF_8") # Need to access PostgreSQL C library directly to use COPY FROM STDINfrom ctypes import *libpq = CDLL("libpq.so.5")PQconnectdb = libpq.PQconnectdbPQconnectdb.restype = c_void_pPQconnectdb.argtypes = [ c_char_p ]PQfinish = libpq.PQfinishPQfinish.argtypes = [ c_void_p ]PQstatus = libpq.PQstatusPQstatus.restype = c_intPQstatus.argtypes = [ c_void_p ]PQexec = libpq.PQexecPQexec.restype = c_void_pPQexec.argtypes = [ c_void_p, c_char_p ]PQresultStatus = libpq.PQresultStatusPQresultStatus.restype = c_intPQresultStatus.argtypes = [ c_void_p ]PQputCopyData = libpq.PQputCopyDataPQputCopyData.restype = c_intPQputCopyData.argtypes = [ c_void_p, c_void_p, c_int ]PQputCopyEnd = libpq.PQputCopyEndPQputCopyEnd.restype = c_intPQputCopyEnd.argtypes = [ c_void_p, c_void_p ] sys.path.append(os.environ['PERF_EXEC_PATH'] + \ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') # These perf imports are not used at present#from perf_trace_context import *#from Core import * perf_db_export_mode = Trueperf_db_export_calls = Falseperf_db_export_callchains = False def printerr(*args, **kw_args): print(*args, file=sys.stderr, **kw_args) def printdate(*args, **kw_args): print(datetime.datetime.today(), *args, sep=' ', **kw_args) def usage(): printerr("Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]"); printerr("where: columns 'all' or 'branches'"); printerr(" calls 'calls' => create calls and call_paths table"); printerr(" callchains 'callchains' => create call_paths table"); printerr(" pyside-version-1 'pyside-version-1' => use pyside version 1"); raise Exception("Too few or bad arguments") if (len(sys.argv) < 2): usage() dbname = sys.argv[1] if (len(sys.argv) >= 3): columns = sys.argv[2]else: columns = "all" if columns not in ("all", "branches"): usage() branches = (columns == "branches") for i in range(3,len(sys.argv)): if (sys.argv[i] == "calls"): perf_db_export_calls = True elif (sys.argv[i] == "callchains"): perf_db_export_callchains = True elif (sys.argv[i] == "pyside-version-1"): pass else: usage() output_dir_name = os.getcwd() + "/" + dbname + "-perf-data"os.mkdir(output_dir_name) def do_query(q, s): if (q.exec_(s)): return raise Exception("Query failed: " + q.lastError().text()) printdate("Creating database...") db = QSqlDatabase.addDatabase('QPSQL')query = QSqlQuery(db)db.setDatabaseName('postgres')db.open()try: do_query(query, 'CREATE DATABASE ' + dbname)except: os.rmdir(output_dir_name) raisequery.finish()query.clear()db.close() db.setDatabaseName(dbname)db.open() query = QSqlQuery(db)do_query(query, 'SET client_min_messages TO WARNING') do_query(query, 'CREATE TABLE selected_events (' 'id bigint NOT NULL,' 'name varchar(80))')do_query(query, 'CREATE TABLE machines (' 'id bigint NOT NULL,' 'pid integer,' 'root_dir varchar(4096))')do_query(query, 'CREATE TABLE threads (' 'id bigint NOT NULL,' 'machine_id bigint,' 'process_id bigint,' 'pid integer,' 'tid integer)')do_query(query, 'CREATE TABLE comms (' 'id bigint NOT NULL,' 'comm varchar(16),' 'c_thread_id bigint,' 'c_time bigint,' 'exec_flag boolean)')do_query(query, 'CREATE TABLE comm_threads (' 'id bigint NOT NULL,' 'comm_id bigint,' 'thread_id bigint)')do_query(query, 'CREATE TABLE dsos (' 'id bigint NOT NULL,' 'machine_id bigint,' 'short_name varchar(256),' 'long_name varchar(4096),' 'build_id varchar(64))')do_query(query, 'CREATE TABLE symbols (' 'id bigint NOT NULL,' 'dso_id bigint,' 'sym_start bigint,' 'sym_end bigint,' 'binding integer,' 'name varchar(2048))')do_query(query, 'CREATE TABLE branch_types (' 'id integer NOT NULL,' 'name varchar(80))') if branches: do_query(query, 'CREATE TABLE samples (' 'id bigint NOT NULL,' 'evsel_id bigint,' 'machine_id bigint,' 'thread_id bigint,' 'comm_id bigint,' 'dso_id bigint,' 'symbol_id bigint,' 'sym_offset bigint,' 'ip bigint,' 'time bigint,' 'cpu integer,' 'to_dso_id bigint,' 'to_symbol_id bigint,' 'to_sym_offset bigint,' 'to_ip bigint,' 'branch_type integer,' 'in_tx boolean,' 'call_path_id bigint,' 'insn_count bigint,' 'cyc_count bigint)')else: do_query(query, 'CREATE TABLE samples (' 'id bigint NOT NULL,' 'evsel_id bigint,' 'machine_id bigint,' 'thread_id bigint,' 'comm_id bigint,' 'dso_id bigint,' 'symbol_id bigint,' 'sym_offset bigint,' 'ip bigint,' 'time bigint,' 'cpu integer,' 'to_dso_id bigint,' 'to_symbol_id bigint,' 'to_sym_offset bigint,' 'to_ip bigint,' 'period bigint,' 'weight bigint,' 'transaction bigint,' 'data_src bigint,' 'branch_type integer,' 'in_tx boolean,' 'call_path_id bigint,' 'insn_count bigint,' 'cyc_count bigint)') if perf_db_export_calls or perf_db_export_callchains: do_query(query, 'CREATE TABLE call_paths (' 'id bigint NOT NULL,' 'parent_id bigint,' 'symbol_id bigint,' 'ip bigint)')if perf_db_export_calls: do_query(query, 'CREATE TABLE calls (' 'id bigint NOT NULL,' 'thread_id bigint,' 'comm_id bigint,' 'call_path_id bigint,' 'call_time bigint,' 'return_time bigint,' 'branch_count bigint,' 'call_id bigint,' 'return_id bigint,' 'parent_call_path_id bigint,' 'flags integer,' 'parent_id bigint,' 'insn_count bigint,' 'cyc_count bigint)') do_query(query, 'CREATE TABLE ptwrite (' 'id bigint NOT NULL,' 'payload bigint,' 'exact_ip boolean)') do_query(query, 'CREATE TABLE cbr (' 'id bigint NOT NULL,' 'cbr integer,' 'mhz integer,' 'percent integer)') do_query(query, 'CREATE TABLE mwait (' 'id bigint NOT NULL,' 'hints integer,' 'extensions integer)') do_query(query, 'CREATE TABLE pwre (' 'id bigint NOT NULL,' 'cstate integer,' 'subcstate integer,' 'hw boolean)') do_query(query, 'CREATE TABLE exstop (' 'id bigint NOT NULL,' 'exact_ip boolean)') do_query(query, 'CREATE TABLE pwrx (' 'id bigint NOT NULL,' 'deepest_cstate integer,' 'last_cstate integer,' 'wake_reason integer)') do_query(query, 'CREATE TABLE context_switches (' 'id bigint NOT NULL,' 'machine_id bigint,' 'time bigint,' 'cpu integer,' 'thread_out_id bigint,' 'comm_out_id bigint,' 'thread_in_id bigint,' 'comm_in_id bigint,' 'flags integer)') do_query(query, 'CREATE VIEW machines_view AS ' 'SELECT ' 'id,' 'pid,' 'root_dir,'Lines 1–500 of 1111. Load more
# export-to-postgresql.py: export perf data to a postgresql database # Copyright (c) 2014, Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, # version 2, as published by the Free Software Foundation. # # This program is distributed in the hope it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. from __future__ import print_function import os import sys import struct import datetime # To use this script you will need to have installed package python-pyside which # provides LGPL-licensed Python bindings for Qt. You will also need the package # libqt4-sql-psql for Qt postgresql support. # # The script assumes postgresql is running on the local machine and that the # user has postgresql permissions to create databases. Examples of installing # postgresql and adding such a user are: # # fedora: # # $ sudo yum install postgresql postgresql-server qt-postgresql # $ sudo su - postgres -c initdb # $ sudo service postgresql start # $ sudo su - postgres # $ createuser -s <your user id here> # Older versions may not support -s, in which case answer the prompt below: # Shall the new role be a superuser? (y/n) y # $ sudo yum install python-pyside # # Alternately, to use Python3 and/or pyside 2, one of the following: # $ sudo yum install python3-pyside # $ pip install --user PySide2 # $ pip3 install --user PySide2 # # ubuntu: # # $ sudo apt-get install postgresql # $ sudo su - postgres # $ createuser -s <your user id here> # $ sudo apt-get install python-pyside.qtsql libqt4-sql-psql # # Alternately, to use Python3 and/or pyside 2, one of the following: # # $ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql # $ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql # $ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql # # An example of using this script with Intel PT: # # $ perf record -e intel_pt//u ls # $ perf script -s ~/libexec/perf-core/scripts/python/export-to-postgresql.py pt_example branches calls # 2015-05-29 12:49:23.464364 Creating database... # 2015-05-29 12:49:26.281717 Writing to intermediate files... # 2015-05-29 12:49:27.190383 Copying to database... # 2015-05-29 12:49:28.140451 Removing intermediate files... # 2015-05-29 12:49:28.147451 Adding primary keys # 2015-05-29 12:49:28.655683 Adding foreign keys # 2015-05-29 12:49:29.365350 Done # # To browse the database, psql can be used e.g. # # $ psql pt_example # pt_example=# select * from samples_view where id < 100; # pt_example=# \d+ # pt_example=# \d+ samples_view # pt_example=# \q # # An example of using the database is provided by the script # exported-sql-viewer.py. Refer to that script for details. # # Tables: # # The tables largely correspond to perf tools' data structures. They are largely self-explanatory. # # samples # # 'samples' is the main table. It represents what instruction was executing at a point in time # when something (a selected event) happened. The memory address is the instruction pointer or 'ip'. # # calls # # 'calls' represents function calls and is related to 'samples' by 'call_id' and 'return_id'. # 'calls' is only created when the 'calls' option to this script is specified. # # call_paths # # 'call_paths' represents all the call stacks. Each 'call' has an associated record in 'call_paths'. # 'calls_paths' is only created when the 'calls' option to this script is specified. # # branch_types # # 'branch_types' provides descriptions for each type of branch. # # comm_threads # # 'comm_threads' shows how 'comms' relates to 'threads'. # # comms # # 'comms' contains a record for each 'comm' - the name given to the executable that is running. # # dsos # # 'dsos' contains a record for each executable file or library. # # machines # # 'machines' can be used to distinguish virtual machines if virtualization is supported. # # selected_events # # 'selected_events' contains a record for each kind of event that has been sampled. # # symbols # # 'symbols' contains a record for each symbol. Only symbols that have samples are present. # # threads # # 'threads' contains a record for each thread. # # Views: # # Most of the tables have views for more friendly display. The views are: # # calls_view # call_paths_view # comm_threads_view # dsos_view # machines_view # samples_view # symbols_view # threads_view # # More examples of browsing the database with psql: # Note that some of the examples are not the most optimal SQL query. # Note that call information is only available if the script's 'calls' option has been used. # # Top 10 function calls (not aggregated by symbol): # # SELECT * FROM calls_view ORDER BY elapsed_time DESC LIMIT 10; # # Top 10 function calls (aggregated by symbol): # # SELECT symbol_id,(SELECT name FROM symbols WHERE id = symbol_id) AS symbol, # SUM(elapsed_time) AS tot_elapsed_time,SUM(branch_count) AS tot_branch_count # FROM calls_view GROUP BY symbol_id ORDER BY tot_elapsed_time DESC LIMIT 10; # # Note that the branch count gives a rough estimation of cpu usage, so functions # that took a long time but have a relatively low branch count must have spent time # waiting. # # Find symbols by pattern matching on part of the name (e.g. names containing 'alloc'): # # SELECT * FROM symbols_view WHERE name LIKE '%alloc%'; # # Top 10 function calls for a specific symbol (e.g. whose symbol_id is 187): # # SELECT * FROM calls_view WHERE symbol_id = 187 ORDER BY elapsed_time DESC LIMIT 10; # # Show function calls made by function in the same context (i.e. same call path) (e.g. one with call_path_id 254): # # SELECT * FROM calls_view WHERE parent_call_path_id = 254; # # Show branches made during a function call (e.g. where call_id is 29357 and return_id is 29370 and tid is 29670) # # SELECT * FROM samples_view WHERE id >= 29357 AND id <= 29370 AND tid = 29670 AND event LIKE 'branches%'; # # Show transactions: # # SELECT * FROM samples_view WHERE event = 'transactions'; # # Note transaction start has 'in_tx' true whereas, transaction end has 'in_tx' false. # Transaction aborts have branch_type_name 'transaction abort' # # Show transaction aborts: # # SELECT * FROM samples_view WHERE event = 'transactions' AND branch_type_name = 'transaction abort'; # # To print a call stack requires walking the call_paths table. For example this python script: # #!/usr/bin/python2 # # import sys # from PySide.QtSql import * # # if __name__ == '__main__': # if (len(sys.argv) < 3): # print >> sys.stderr, "Usage is: printcallstack.py <database name> <call_path_id>" # raise Exception("Too few arguments") # dbname = sys.argv[1] # call_path_id = sys.argv[2] # db = QSqlDatabase.addDatabase('QPSQL') # db.setDatabaseName(dbname) # if not db.open(): # raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text()) # query = QSqlQuery(db) # print " id ip symbol_id symbol dso_id dso_short_name" # while call_path_id != 0 and call_path_id != 1: # ret = query.exec_('SELECT * FROM call_paths_view WHERE id = ' + str(call_path_id)) # if not ret: # raise Exception("Query failed: " + query.lastError().text()) # if not query.next(): # raise Exception("Query failed") # print "{0:>6} {1:>10} {2:>9} {3:<30} {4:>6} {5:<30}".format(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4), query.value(5)) # call_path_id = query.value(6) pyside_version_1 = True if not "pyside-version-1" in sys.argv: try: from PySide2.QtSql import * pyside_version_1 = False except: pass if pyside_version_1: from PySide.QtSql import * if sys.version_info < (3, 0): def toserverstr(str): return str def toclientstr(str): return str else: # Assume UTF-8 server_encoding and client_encoding def toserverstr(str): return bytes(str, "UTF_8") def toclientstr(str): return bytes(str, "UTF_8") # Need to access PostgreSQL C library directly to use COPY FROM STDIN from ctypes import * libpq = CDLL("libpq.so.5") PQconnectdb = libpq.PQconnectdb PQconnectdb.restype = c_void_p PQconnectdb.argtypes = [ c_char_p ] PQfinish = libpq.PQfinish PQfinish.argtypes = [ c_void_p ] PQstatus = libpq.PQstatus PQstatus.restype = c_int PQstatus.argtypes = [ c_void_p ] PQexec = libpq.PQexec PQexec.restype = c_void_p PQexec.argtypes = [ c_void_p, c_char_p ] PQresultStatus = libpq.PQresultStatus PQresultStatus.restype = c_int PQresultStatus.argtypes = [ c_void_p ] PQputCopyData = libpq.PQputCopyData PQputCopyData.restype = c_int PQputCopyData.argtypes = [ c_void_p, c_void_p, c_int ] PQputCopyEnd = libpq.PQputCopyEnd PQputCopyEnd.restype = c_int PQputCopyEnd.argtypes = [ c_void_p, c_void_p ] sys.path.append(os.environ['PERF_EXEC_PATH'] + \ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') # These perf imports are not used at present #from perf_trace_context import * #from Core import * perf_db_export_mode = True perf_db_export_calls = False perf_db_export_callchains = False def printerr(*args, **kw_args): print(*args, file=sys.stderr, **kw_args) def printdate(*args, **kw_args): print(datetime.datetime.today(), *args, sep=' ', **kw_args) def usage(): printerr("Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]"); printerr("where: columns 'all' or 'branches'"); printerr(" calls 'calls' => create calls and call_paths table"); printerr(" callchains 'callchains' => create call_paths table"); printerr(" pyside-version-1 'pyside-version-1' => use pyside version 1"); raise Exception("Too few or bad arguments") if (len(sys.argv) < 2): usage() dbname = sys.argv[1] if (len(sys.argv) >= 3): columns = sys.argv[2] else: columns = "all" if columns not in ("all", "branches"): usage() branches = (columns == "branches") for i in range(3,len(sys.argv)): if (sys.argv[i] == "calls"): perf_db_export_calls = True elif (sys.argv[i] == "callchains"): perf_db_export_callchains = True elif (sys.argv[i] == "pyside-version-1"): pass else: usage() output_dir_name = os.getcwd() + "/" + dbname + "-perf-data" os.mkdir(output_dir_name) def do_query(q, s): if (q.exec_(s)): return raise Exception("Query failed: " + q.lastError().text()) printdate("Creating database...") db = QSqlDatabase.addDatabase('QPSQL') query = QSqlQuery(db) db.setDatabaseName('postgres') db.open() try: do_query(query, 'CREATE DATABASE ' + dbname) except: os.rmdir(output_dir_name) raise query.finish() query.clear() db.close() db.setDatabaseName(dbname) db.open() query = QSqlQuery(db) do_query(query, 'SET client_min_messages TO WARNING') do_query(query, 'CREATE TABLE selected_events (' 'id bigint NOT NULL,' 'name varchar(80))') do_query(query, 'CREATE TABLE machines (' 'id bigint NOT NULL,' 'pid integer,' 'root_dir varchar(4096))') do_query(query, 'CREATE TABLE threads (' 'id bigint NOT NULL,' 'machine_id bigint,' 'process_id bigint,' 'pid integer,' 'tid integer)') do_query(query, 'CREATE TABLE comms (' 'id bigint NOT NULL,' 'comm varchar(16),' 'c_thread_id bigint,' 'c_time bigint,' 'exec_flag boolean)') do_query(query, 'CREATE TABLE comm_threads (' 'id bigint NOT NULL,' 'comm_id bigint,' 'thread_id bigint)') do_query(query, 'CREATE TABLE dsos (' 'id bigint NOT NULL,' 'machine_id bigint,' 'short_name varchar(256),' 'long_name varchar(4096),' 'build_id varchar(64))') do_query(query, 'CREATE TABLE symbols (' 'id bigint NOT NULL,' 'dso_id bigint,' 'sym_start bigint,' 'sym_end bigint,' 'binding integer,' 'name varchar(2048))') do_query(query, 'CREATE TABLE branch_types (' 'id integer NOT NULL,' 'name varchar(80))') if branches: do_query(query, 'CREATE TABLE samples (' 'id bigint NOT NULL,' 'evsel_id bigint,' 'machine_id bigint,' 'thread_id bigint,' 'comm_id bigint,' 'dso_id bigint,' 'symbol_id bigint,' 'sym_offset bigint,' 'ip bigint,' 'time bigint,' 'cpu integer,' 'to_dso_id bigint,' 'to_symbol_id bigint,' 'to_sym_offset bigint,' 'to_ip bigint,' 'branch_type integer,' 'in_tx boolean,' 'call_path_id bigint,' 'insn_count bigint,' 'cyc_count bigint)') else: do_query(query, 'CREATE TABLE samples (' 'id bigint NOT NULL,' 'evsel_id bigint,' 'machine_id bigint,' 'thread_id bigint,' 'comm_id bigint,' 'dso_id bigint,' 'symbol_id bigint,' 'sym_offset bigint,' 'ip bigint,' 'time bigint,' 'cpu integer,' 'to_dso_id bigint,' 'to_symbol_id bigint,' 'to_sym_offset bigint,' 'to_ip bigint,' 'period bigint,' 'weight bigint,' 'transaction bigint,' 'data_src bigint,' 'branch_type integer,' 'in_tx boolean,' 'call_path_id bigint,' 'insn_count bigint,' 'cyc_count bigint)') if perf_db_export_calls or perf_db_export_callchains: do_query(query, 'CREATE TABLE call_paths (' 'id bigint NOT NULL,' 'parent_id bigint,' 'symbol_id bigint,' 'ip bigint)') if perf_db_export_calls: do_query(query, 'CREATE TABLE calls (' 'id bigint NOT NULL,' 'thread_id bigint,' 'comm_id bigint,' 'call_path_id bigint,' 'call_time bigint,' 'return_time bigint,' 'branch_count bigint,' 'call_id bigint,' 'return_id bigint,' 'parent_call_path_id bigint,' 'flags integer,' 'parent_id bigint,' 'insn_count bigint,' 'cyc_count bigint)') do_query(query, 'CREATE TABLE ptwrite (' 'id bigint NOT NULL,' 'payload bigint,' 'exact_ip boolean)') do_query(query, 'CREATE TABLE cbr (' 'id bigint NOT NULL,' 'cbr integer,' 'mhz integer,' 'percent integer)') do_query(query, 'CREATE TABLE mwait (' 'id bigint NOT NULL,' 'hints integer,' 'extensions integer)') do_query(query, 'CREATE TABLE pwre (' 'id bigint NOT NULL,' 'cstate integer,' 'subcstate integer,' 'hw boolean)') do_query(query, 'CREATE TABLE exstop (' 'id bigint NOT NULL,' 'exact_ip boolean)') do_query(query, 'CREATE TABLE pwrx (' 'id bigint NOT NULL,' 'deepest_cstate integer,' 'last_cstate integer,' 'wake_reason integer)') do_query(query, 'CREATE TABLE context_switches (' 'id bigint NOT NULL,' 'machine_id bigint,' 'time bigint,' 'cpu integer,' 'thread_out_id bigint,' 'comm_out_id bigint,' 'thread_in_id bigint,' 'comm_in_id bigint,' 'flags integer)') do_query(query, 'CREATE VIEW machines_view AS ' 'SELECT ' 'id,' 'pid,' 'root_dir,'