diff options
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 | 98 |
2 files changed, 101 insertions, 12 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 d8f6df0093d6..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 | ||
@@ -123,6 +131,10 @@ do_query(query, 'CREATE TABLE symbols (' | |||
123 | 'sym_end bigint,' | 131 | 'sym_end bigint,' |
124 | 'binding integer,' | 132 | 'binding integer,' |
125 | 'name varchar(2048))') | 133 | 'name varchar(2048))') |
134 | do_query(query, 'CREATE TABLE branch_types (' | ||
135 | 'id integer NOT NULL,' | ||
136 | 'name varchar(80))') | ||
137 | |||
126 | if branches: | 138 | if branches: |
127 | do_query(query, 'CREATE TABLE samples (' | 139 | do_query(query, 'CREATE TABLE samples (' |
128 | 'id bigint NOT NULL,' | 140 | 'id bigint NOT NULL,' |
@@ -139,7 +151,9 @@ if branches: | |||
139 | 'to_dso_id bigint,' | 151 | 'to_dso_id bigint,' |
140 | 'to_symbol_id bigint,' | 152 | 'to_symbol_id bigint,' |
141 | 'to_sym_offset bigint,' | 153 | 'to_sym_offset bigint,' |
142 | 'to_ip bigint)') | 154 | 'to_ip bigint,' |
155 | 'branch_type integer,' | ||
156 | 'in_tx boolean)') | ||
143 | else: | 157 | else: |
144 | do_query(query, 'CREATE TABLE samples (' | 158 | do_query(query, 'CREATE TABLE samples (' |
145 | 'id bigint NOT NULL,' | 159 | 'id bigint NOT NULL,' |
@@ -160,7 +174,28 @@ else: | |||
160 | 'period bigint,' | 174 | 'period bigint,' |
161 | 'weight bigint,' | 175 | 'weight bigint,' |
162 | 'transaction bigint,' | 176 | 'transaction bigint,' |
163 | 'data_src bigint)') | 177 | 'data_src bigint,' |
178 | 'branch_type integer,' | ||
179 | 'in_tx boolean)') | ||
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)') | ||
164 | 199 | ||
165 | do_query(query, 'CREATE VIEW samples_view AS ' | 200 | do_query(query, 'CREATE VIEW samples_view AS ' |
166 | 'SELECT ' | 201 | 'SELECT ' |
@@ -178,7 +213,9 @@ do_query(query, 'CREATE VIEW samples_view AS ' | |||
178 | 'to_hex(to_ip) AS to_ip_hex,' | 213 | 'to_hex(to_ip) AS to_ip_hex,' |
179 | '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,' | 214 | '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,' |
180 | 'to_sym_offset,' | 215 | 'to_sym_offset,' |
181 | '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name' | 216 | '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,' |
217 | '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,' | ||
218 | 'in_tx' | ||
182 | ' FROM samples') | 219 | ' FROM samples') |
183 | 220 | ||
184 | 221 | ||
@@ -234,7 +271,11 @@ comm_file = open_output_file("comm_table.bin") | |||
234 | comm_thread_file = open_output_file("comm_thread_table.bin") | 271 | comm_thread_file = open_output_file("comm_thread_table.bin") |
235 | dso_file = open_output_file("dso_table.bin") | 272 | dso_file = open_output_file("dso_table.bin") |
236 | symbol_file = open_output_file("symbol_table.bin") | 273 | symbol_file = open_output_file("symbol_table.bin") |
274 | branch_type_file = open_output_file("branch_type_table.bin") | ||
237 | 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") | ||
238 | 279 | ||
239 | def trace_begin(): | 280 | def trace_begin(): |
240 | print datetime.datetime.today(), "Writing to intermediate files..." | 281 | print datetime.datetime.today(), "Writing to intermediate files..." |
@@ -245,6 +286,9 @@ def trace_begin(): | |||
245 | comm_table(0, "unknown") | 286 | comm_table(0, "unknown") |
246 | dso_table(0, 0, "unknown", "unknown", "") | 287 | dso_table(0, 0, "unknown", "unknown", "") |
247 | 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) | ||
248 | 292 | ||
249 | unhandled_count = 0 | 293 | unhandled_count = 0 |
250 | 294 | ||
@@ -257,7 +301,11 @@ def trace_end(): | |||
257 | copy_output_file(comm_thread_file, "comm_threads") | 301 | copy_output_file(comm_thread_file, "comm_threads") |
258 | copy_output_file(dso_file, "dsos") | 302 | copy_output_file(dso_file, "dsos") |
259 | copy_output_file(symbol_file, "symbols") | 303 | copy_output_file(symbol_file, "symbols") |
304 | copy_output_file(branch_type_file, "branch_types") | ||
260 | 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") | ||
261 | 309 | ||
262 | print datetime.datetime.today(), "Removing intermediate files..." | 310 | print datetime.datetime.today(), "Removing intermediate files..." |
263 | remove_output_file(evsel_file) | 311 | remove_output_file(evsel_file) |
@@ -267,7 +315,11 @@ def trace_end(): | |||
267 | remove_output_file(comm_thread_file) | 315 | remove_output_file(comm_thread_file) |
268 | remove_output_file(dso_file) | 316 | remove_output_file(dso_file) |
269 | remove_output_file(symbol_file) | 317 | remove_output_file(symbol_file) |
318 | remove_output_file(branch_type_file) | ||
270 | 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) | ||
271 | os.rmdir(output_dir_name) | 323 | os.rmdir(output_dir_name) |
272 | print datetime.datetime.today(), "Adding primary keys" | 324 | print datetime.datetime.today(), "Adding primary keys" |
273 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') | 325 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') |
@@ -277,7 +329,11 @@ def trace_end(): | |||
277 | do_query(query, 'ALTER TABLE comm_threads ADD PRIMARY KEY (id)') | 329 | do_query(query, 'ALTER TABLE comm_threads ADD PRIMARY KEY (id)') |
278 | do_query(query, 'ALTER TABLE dsos ADD PRIMARY KEY (id)') | 330 | do_query(query, 'ALTER TABLE dsos ADD PRIMARY KEY (id)') |
279 | do_query(query, 'ALTER TABLE symbols ADD PRIMARY KEY (id)') | 331 | do_query(query, 'ALTER TABLE symbols ADD PRIMARY KEY (id)') |
332 | do_query(query, 'ALTER TABLE branch_types ADD PRIMARY KEY (id)') | ||
280 | 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)') | ||
281 | 337 | ||
282 | print datetime.datetime.today(), "Adding foreign keys" | 338 | print datetime.datetime.today(), "Adding foreign keys" |
283 | do_query(query, 'ALTER TABLE threads ' | 339 | do_query(query, 'ALTER TABLE threads ' |
@@ -299,6 +355,18 @@ def trace_end(): | |||
299 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id),' | 355 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id),' |
300 | 'ADD CONSTRAINT todsofk FOREIGN KEY (to_dso_id) REFERENCES dsos (id),' | 356 | 'ADD CONSTRAINT todsofk FOREIGN KEY (to_dso_id) REFERENCES dsos (id),' |
301 | '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)') | ||
302 | 370 | ||
303 | if (unhandled_count): | 371 | if (unhandled_count): |
304 | print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" | 372 | print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" |
@@ -352,9 +420,25 @@ def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x | |||
352 | value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name) | 420 | value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name) |
353 | symbol_file.write(value) | 421 | symbol_file.write(value) |
354 | 422 | ||
355 | def sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, symbol_id, sym_offset, ip, time, cpu, to_dso_id, to_symbol_id, to_sym_offset, to_ip, period, weight, transaction, data_src, *x): | 423 | def branch_type_table(branch_type, name, *x): |
424 | n = len(name) | ||
425 | fmt = "!hiii" + str(n) + "s" | ||
426 | value = struct.pack(fmt, 2, 4, branch_type, n, name) | ||
427 | branch_type_file.write(value) | ||
428 | |||
429 | def sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, symbol_id, sym_offset, ip, time, cpu, to_dso_id, to_symbol_id, to_sym_offset, to_ip, period, weight, transaction, data_src, branch_type, in_tx, *x): | ||
356 | if branches: | 430 | if branches: |
357 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiq", 15, 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) | 431 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiiiB", 17, 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, 4, branch_type, 1, in_tx) |
358 | else: | 432 | else: |
359 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiq", 19, 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) | 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) |
360 | 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) | ||