@@ -156,6 +156,18 @@ def _parse_args():
156
156
help = "always, never or auto, allowing configuring color output"
157
157
" via the command line" ,
158
158
)
159
+ parser .add_argument (
160
+ "--csv" ,
161
+ default = "" ,
162
+ help = "Write trace to file selected by user. Options, like --ns or --extended"
163
+ "-times are used." ,
164
+ )
165
+ parser .add_argument (
166
+ "--csv-summary" ,
167
+ default = "" ,
168
+ help = "Write summary to file selected by user. Options, like --ns or"
169
+ " --summary-extended are used." ,
170
+ )
159
171
args = parser .parse_args ()
160
172
args .tid_renames = dict ()
161
173
@@ -275,7 +287,6 @@ def _update_max_entries(self):
275
287
276
288
277
289
278
-
279
290
class Summary (object ):
280
291
"""
281
292
Primary instance for calculating the summary output. Processes the whole trace to
@@ -327,7 +338,7 @@ def _print_header(self):
327
338
sum (db ["inter_times" ].values ()) - 4 * decimal_precision
328
339
)
329
340
_header += ("Max Inter Task Times" ,)
330
- print (fmt .format (* _header ))
341
+ fd_sum . write (fmt .format (* _header ) + " \n " )
331
342
332
343
def _column_titles (self ):
333
344
"""
@@ -336,34 +347,58 @@ def _column_titles(self):
336
347
values are being displayed in grey. Thus in their format two additional {},
337
348
are placed for color set and reset.
338
349
"""
350
+ separator , fix_csv_align = _prepare_fmt_sep ()
339
351
decimal_precision , time_precision = _prepare_fmt_precision ()
340
- fmt = " {{:>{}}}" .format (db ["task_info" ]["pid" ])
341
- fmt += " {{:>{}}}" .format (db ["task_info" ]["tid" ])
342
- fmt += " {{:>{}}}" .format (db ["task_info" ]["comm" ])
343
- fmt += " {{:>{}}}" .format (db ["runtime_info" ]["runs" ])
344
- fmt += " {{:>{}}}" .format (db ["runtime_info" ]["acc" ])
345
- fmt += " {{:>{}}}" .format (db ["runtime_info" ]["mean" ])
346
- fmt += " {{:>{}}}" .format (db ["runtime_info" ]["median" ])
347
- fmt += " {{:>{}}}" .format (db ["runtime_info" ]["min" ] - decimal_precision )
348
- fmt += " {{:>{}}}" .format (db ["runtime_info" ]["max" ] - decimal_precision )
349
- fmt += " {{}}{{:>{}}}{{}}" .format (db ["runtime_info" ]["max_at" ] - time_precision )
352
+ fmt = "{{:>{}}}" .format (db ["task_info" ]["pid" ] * fix_csv_align )
353
+ fmt += "{}{{:>{}}}" .format (separator , db ["task_info" ]["tid" ] * fix_csv_align )
354
+ fmt += "{}{{:>{}}}" .format (separator , db ["task_info" ]["comm" ] * fix_csv_align )
355
+ fmt += "{}{{:>{}}}" .format (separator , db ["runtime_info" ]["runs" ] * fix_csv_align )
356
+ fmt += "{}{{:>{}}}" .format (separator , db ["runtime_info" ]["acc" ] * fix_csv_align )
357
+ fmt += "{}{{:>{}}}" .format (separator , db ["runtime_info" ]["mean" ] * fix_csv_align )
358
+ fmt += "{}{{:>{}}}" .format (
359
+ separator , db ["runtime_info" ]["median" ] * fix_csv_align
360
+ )
361
+ fmt += "{}{{:>{}}}" .format (
362
+ separator , (db ["runtime_info" ]["min" ] - decimal_precision ) * fix_csv_align
363
+ )
364
+ fmt += "{}{{:>{}}}" .format (
365
+ separator , (db ["runtime_info" ]["max" ] - decimal_precision ) * fix_csv_align
366
+ )
367
+ fmt += "{}{{}}{{:>{}}}{{}}" .format (
368
+ separator , (db ["runtime_info" ]["max_at" ] - time_precision ) * fix_csv_align
369
+ )
350
370
351
371
column_titles = ("PID" , "TID" , "Comm" )
352
372
column_titles += ("Runs" , "Accumulated" , "Mean" , "Median" , "Min" , "Max" )
353
- column_titles += (_COLORS ["grey" ], "At" , _COLORS ["reset" ])
373
+ column_titles += (_COLORS ["grey" ], "Max At" , _COLORS ["reset" ])
354
374
355
375
if args .summary_extended :
356
- fmt += " {{:>{}}}" .format (db ["inter_times" ]["out_in" ] - decimal_precision )
357
- fmt += " {{}}{{:>{}}}{{}}" .format (
358
- db ["inter_times" ]["inter_at" ] - time_precision
376
+ fmt += "{}{{:>{}}}" .format (
377
+ separator ,
378
+ (db ["inter_times" ]["out_in" ] - decimal_precision ) * fix_csv_align
379
+ )
380
+ fmt += "{}{{}}{{:>{}}}{{}}" .format (
381
+ separator ,
382
+ (db ["inter_times" ]["inter_at" ] - time_precision ) * fix_csv_align
383
+ )
384
+ fmt += "{}{{:>{}}}" .format (
385
+ separator ,
386
+ (db ["inter_times" ]["out_out" ] - decimal_precision ) * fix_csv_align
387
+ )
388
+ fmt += "{}{{:>{}}}" .format (
389
+ separator ,
390
+ (db ["inter_times" ]["in_in" ] - decimal_precision ) * fix_csv_align
391
+ )
392
+ fmt += "{}{{:>{}}}" .format (
393
+ separator ,
394
+ (db ["inter_times" ]["in_out" ] - decimal_precision ) * fix_csv_align
359
395
)
360
- fmt += " {{:>{}}}" .format (db ["inter_times" ]["out_out" ] - decimal_precision )
361
- fmt += " {{:>{}}}" .format (db ["inter_times" ]["in_in" ] - decimal_precision )
362
- fmt += " {{:>{}}}" .format (db ["inter_times" ]["in_out" ] - decimal_precision )
363
396
364
397
column_titles += ("Out-In" , _COLORS ["grey" ], "Max At" , _COLORS ["reset" ],
365
398
"Out-Out" , "In-In" , "In-Out" )
366
- print (fmt .format (* column_titles ))
399
+
400
+ fd_sum .write (fmt .format (* column_titles ) + "\n " )
401
+
367
402
368
403
def _task_stats (self ):
369
404
"""calculates the stats of every task and constructs the printable summary"""
@@ -414,39 +449,53 @@ def _task_stats(self):
414
449
self ._calc_alignments_summary (align_helper )
415
450
416
451
def _format_stats (self ):
452
+ separator , fix_csv_align = _prepare_fmt_sep ()
417
453
decimal_precision , time_precision = _prepare_fmt_precision ()
418
- fmt = " {{:>{}d}}" .format (db ["task_info" ]["pid" ])
419
- fmt += " {{:>{}d}}" .format (db ["task_info" ]["tid" ])
420
- fmt += " {{:>{}}}" .format (db ["task_info" ]["comm" ])
421
- fmt += " {{:>{}d}}" .format (db ["runtime_info" ]["runs" ])
422
- fmt += " {{:>{}.{}f}}" .format (db ["runtime_info" ]["acc" ], time_precision )
423
- fmt += " {{}}{{:>{}.{}f}}" .format (db ["runtime_info" ]["mean" ], time_precision )
424
- fmt += " {{:>{}.{}f}}" .format (db ["runtime_info" ]["median" ], time_precision )
425
- fmt += " {{:>{}.{}f}}" .format (
426
- db ["runtime_info" ]["min" ] - decimal_precision , time_precision
427
- )
428
- fmt += " {{:>{}.{}f}}" .format (
429
- db ["runtime_info" ]["max" ] - decimal_precision , time_precision
430
- )
431
- fmt += " {{}}{{:>{}.{}f}}{{}}{{}}" .format (
432
- db ["runtime_info" ]["max_at" ] - time_precision , decimal_precision
454
+ len_pid = db ["task_info" ]["pid" ] * fix_csv_align
455
+ len_tid = db ["task_info" ]["tid" ] * fix_csv_align
456
+ len_comm = db ["task_info" ]["comm" ] * fix_csv_align
457
+ len_runs = db ["runtime_info" ]["runs" ] * fix_csv_align
458
+ len_acc = db ["runtime_info" ]["acc" ] * fix_csv_align
459
+ len_mean = db ["runtime_info" ]["mean" ] * fix_csv_align
460
+ len_median = db ["runtime_info" ]["median" ] * fix_csv_align
461
+ len_min = (db ["runtime_info" ]["min" ] - decimal_precision ) * fix_csv_align
462
+ len_max = (db ["runtime_info" ]["max" ] - decimal_precision ) * fix_csv_align
463
+ len_max_at = (db ["runtime_info" ]["max_at" ] - time_precision ) * fix_csv_align
464
+ if args .summary_extended :
465
+ len_out_in = (
466
+ db ["inter_times" ]["out_in" ] - decimal_precision
467
+ ) * fix_csv_align
468
+ len_inter_at = (
469
+ db ["inter_times" ]["inter_at" ] - time_precision
470
+ ) * fix_csv_align
471
+ len_out_out = (
472
+ db ["inter_times" ]["out_out" ] - decimal_precision
473
+ ) * fix_csv_align
474
+ len_in_in = (db ["inter_times" ]["in_in" ] - decimal_precision ) * fix_csv_align
475
+ len_in_out = (
476
+ db ["inter_times" ]["in_out" ] - decimal_precision
477
+ ) * fix_csv_align
478
+
479
+ fmt = "{{:{}d}}" .format (len_pid )
480
+ fmt += "{}{{:{}d}}" .format (separator , len_tid )
481
+ fmt += "{}{{:>{}}}" .format (separator , len_comm )
482
+ fmt += "{}{{:{}d}}" .format (separator , len_runs )
483
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_acc , time_precision )
484
+ fmt += "{}{{}}{{:{}.{}f}}" .format (separator , len_mean , time_precision )
485
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_median , time_precision )
486
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_min , time_precision )
487
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_max , time_precision )
488
+ fmt += "{}{{}}{{:{}.{}f}}{{}}{{}}" .format (
489
+ separator , len_max_at , decimal_precision
433
490
)
434
491
if args .summary_extended :
435
- fmt += " {{:>{}.{}f}}" .format (
436
- db ["inter_times" ]["out_in" ] - decimal_precision , time_precision
437
- )
438
- fmt += " {{}}{{:>{}.{}f}}{{}}" .format (
439
- db ["inter_times" ]["inter_at" ] - time_precision , decimal_precision
440
- )
441
- fmt += " {{:>{}.{}f}}" .format (
442
- db ["inter_times" ]["out_out" ] - decimal_precision , time_precision
443
- )
444
- fmt += " {{:>{}.{}f}}" .format (
445
- db ["inter_times" ]["in_in" ] - decimal_precision , time_precision
446
- )
447
- fmt += " {{:>{}.{}f}}" .format (
448
- db ["inter_times" ]["in_out" ] - decimal_precision , time_precision
492
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_out_in , time_precision )
493
+ fmt += "{}{{}}{{:{}.{}f}}{{}}" .format (
494
+ separator , len_inter_at , decimal_precision
449
495
)
496
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_out_out , time_precision )
497
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_in_in , time_precision )
498
+ fmt += "{}{{:{}.{}f}}" .format (separator , len_in_out , time_precision )
450
499
return fmt
451
500
452
501
@@ -467,13 +516,15 @@ def _calc_alignments_summary(self, align_helper):
467
516
468
517
469
518
def print (self ):
470
- print ("\n Summary" )
471
519
self ._task_stats ()
472
- self ._print_header ()
473
- self ._column_titles ()
474
520
fmt = self ._format_stats ()
521
+
522
+ if not args .csv_summary :
523
+ print ("\n Summary" )
524
+ self ._print_header ()
525
+ self ._column_titles ()
475
526
for i in range (len (self ._body )):
476
- print (fmt .format (* tuple (self ._body [i ])))
527
+ fd_sum . write (fmt .format (* tuple (self ._body [i ])) + " \n " )
477
528
478
529
479
530
@@ -531,37 +582,45 @@ def _filter_non_printable(unfiltered):
531
582
532
583
533
584
def _fmt_header ():
534
- fmt = "{{:>{}}}" .format (LEN_SWITCHED_IN )
535
- fmt += " {{:>{}}}" .format (LEN_SWITCHED_OUT )
536
- fmt += " {{:>{}}}" .format (LEN_CPU )
537
- fmt += " {{:>{}}}" .format (LEN_PID )
538
- fmt += " {{:>{}}}" .format (LEN_TID )
539
- fmt += " {{:>{}}}" .format (LEN_COMM )
540
- fmt += " {{:>{}}}" .format (LEN_RUNTIME )
541
- fmt += " {{:>{}}}" .format (LEN_OUT_IN )
585
+ separator , fix_csv_align = _prepare_fmt_sep ()
586
+ fmt = "{{:>{}}}" .format (LEN_SWITCHED_IN * fix_csv_align )
587
+ fmt += "{}{{:>{}}}" .format (separator , LEN_SWITCHED_OUT * fix_csv_align )
588
+ fmt += "{}{{:>{}}}" .format (separator , LEN_CPU * fix_csv_align )
589
+ fmt += "{}{{:>{}}}" .format (separator , LEN_PID * fix_csv_align )
590
+ fmt += "{}{{:>{}}}" .format (separator , LEN_TID * fix_csv_align )
591
+ fmt += "{}{{:>{}}}" .format (separator , LEN_COMM * fix_csv_align )
592
+ fmt += "{}{{:>{}}}" .format (separator , LEN_RUNTIME * fix_csv_align )
593
+ fmt += "{}{{:>{}}}" .format (separator , LEN_OUT_IN * fix_csv_align )
542
594
if args .extended_times :
543
- fmt += " {{ :>{}}}" .format (LEN_OUT_OUT )
544
- fmt += " {{ :>{}}}" .format (LEN_IN_IN )
545
- fmt += " {{ :>{}}}" .format (LEN_IN_OUT )
595
+ fmt += "{}{{ :>{}}}" .format (separator , LEN_OUT_OUT * fix_csv_align )
596
+ fmt += "{}{{ :>{}}}" .format (separator , LEN_IN_IN * fix_csv_align )
597
+ fmt += "{}{{ :>{}}}" .format (separator , LEN_IN_OUT * fix_csv_align )
546
598
return fmt
547
599
548
600
549
601
def _fmt_body ():
602
+ separator , fix_csv_align = _prepare_fmt_sep ()
550
603
decimal_precision , time_precision = _prepare_fmt_precision ()
551
- fmt = "{{}}{{:{}.{}f}}" .format (LEN_SWITCHED_IN , decimal_precision )
552
- fmt += " {{:{}.{}f}}" .format (LEN_SWITCHED_OUT , decimal_precision )
553
- fmt += " {{:{}d}}" .format (LEN_CPU )
554
- fmt += " {{:{}d}}" .format (LEN_PID )
555
- fmt += " {{}}{{:{}d}}{{}}" .format (LEN_TID )
556
- fmt += " {{}}{{:>{}}}" .format (LEN_COMM )
557
- fmt += " {{:{}.{}f}}" .format (LEN_RUNTIME , time_precision )
604
+ fmt = "{{}}{{:{}.{}f}}" .format (LEN_SWITCHED_IN * fix_csv_align , decimal_precision )
605
+ fmt += "{}{{:{}.{}f}}" .format (
606
+ separator , LEN_SWITCHED_OUT * fix_csv_align , decimal_precision
607
+ )
608
+ fmt += "{}{{:{}d}}" .format (separator , LEN_CPU * fix_csv_align )
609
+ fmt += "{}{{:{}d}}" .format (separator , LEN_PID * fix_csv_align )
610
+ fmt += "{}{{}}{{:{}d}}{{}}" .format (separator , LEN_TID * fix_csv_align )
611
+ fmt += "{}{{}}{{:>{}}}" .format (separator , LEN_COMM * fix_csv_align )
612
+ fmt += "{}{{:{}.{}f}}" .format (separator , LEN_RUNTIME * fix_csv_align , time_precision )
558
613
if args .extended_times :
559
- fmt += " {{:{}.{}f}}" .format (LEN_OUT_IN , time_precision )
560
- fmt += " {{:{}.{}f}}" .format (LEN_OUT_OUT , time_precision )
561
- fmt += " {{:{}.{}f}}" .format (LEN_IN_IN , time_precision )
562
- fmt += " {{:{}.{}f}}{{}}" .format (LEN_IN_OUT , time_precision )
614
+ fmt += "{}{{:{}.{}f}}" .format (separator , LEN_OUT_IN * fix_csv_align , time_precision )
615
+ fmt += "{}{{:{}.{}f}}" .format (separator , LEN_OUT_OUT * fix_csv_align , time_precision )
616
+ fmt += "{}{{:{}.{}f}}" .format (separator , LEN_IN_IN * fix_csv_align , time_precision )
617
+ fmt += "{}{{:{}.{}f}}{{}}" .format (
618
+ separator , LEN_IN_OUT * fix_csv_align , time_precision
619
+ )
563
620
else :
564
- fmt += " {{:{}.{}f}}{{}}" .format (LEN_OUT_IN , time_precision )
621
+ fmt += "{}{{:{}.{}f}}{{}}" .format (
622
+ separator , LEN_OUT_IN * fix_csv_align , time_precision
623
+ )
565
624
return fmt
566
625
567
626
@@ -571,7 +630,8 @@ def _print_header():
571
630
"Time Out-In" )
572
631
if args .extended_times :
573
632
header += ("Time Out-Out" , "Time In-In" , "Time In-Out" )
574
- print (fmt .format (* header ))
633
+ fd_task .write (fmt .format (* header ) + "\n " )
634
+
575
635
576
636
577
637
def _print_task_finish (task ):
@@ -583,7 +643,6 @@ def _print_task_finish(task):
583
643
in_in = - 1
584
644
in_out = - 1
585
645
fmt = _fmt_body ()
586
-
587
646
# depending on user provided highlight option we change the color
588
647
# for particular tasks
589
648
if str (task .tid ) in args .highlight_tasks_map :
@@ -612,16 +671,22 @@ def _print_task_finish(task):
612
671
out_out = timespan_gap_tid .out_out
613
672
in_in = timespan_gap_tid .in_in
614
673
in_out = timespan_gap_tid .in_out
674
+
675
+
615
676
if args .extended_times :
616
- print ( fmt .format (c_row_set , task .time_in (), task .time_out (), task .cpu , task . pid ,
617
- c_tid_set , task .tid , c_tid_reset , c_row_set , task .comm ,
677
+ line_out = fmt .format (c_row_set , task .time_in (), task .time_out (), task .cpu ,
678
+ task . pid , c_tid_set , task .tid , c_tid_reset , c_row_set , task .comm ,
618
679
task .runtime (time_unit ), out_in , out_out , in_in , in_out ,
619
- c_row_reset ))
680
+ c_row_reset ) + " \n "
620
681
else :
621
- print (fmt .format (c_row_set , task .time_in (), task .time_out (), task .cpu , task .pid ,
622
- c_tid_set , task .tid , c_tid_reset , c_row_set , task .comm ,
623
- task .runtime (time_unit ), out_in , c_row_reset ))
624
-
682
+ line_out = fmt .format (c_row_set , task .time_in (), task .time_out (), task .cpu ,
683
+ task .pid , c_tid_set , task .tid , c_tid_reset , c_row_set , task .comm ,
684
+ task .runtime (time_unit ), out_in , c_row_reset ) + "\n "
685
+ try :
686
+ fd_task .write (line_out )
687
+ except (IOError ):
688
+ # don't mangle the output if user SIGINT this script
689
+ sys .exit ()
625
690
626
691
def _record_cleanup (_list ):
627
692
"""
@@ -733,10 +798,19 @@ def _argument_filter_sanity_check():
733
798
)
734
799
if args .time_limit and (args .summary or args .summary_only or args .summary_extended ):
735
800
sys .exit ("Error: Cannot set time limit and print summary" )
736
-
801
+ if args .csv_summary :
802
+ args .summary = True
803
+ if args .csv == args .csv_summary :
804
+ sys .exit ("Error: Chosen files for csv and csv summary are the same" )
805
+ if args .csv and (args .summary_extended or args .summary ) and not args .csv_summary :
806
+ sys .exit ("Error: No file chosen to write summary to. Choose with --csv-summary "
807
+ "<file>" )
808
+ if args .csv and args .summary_only :
809
+ sys .exit ("Error: --csv chosen and --summary-only. Standard task would not be"
810
+ "written to csv file." )
737
811
738
812
def _argument_prepare_check ():
739
- global time_unit
813
+ global time_unit , fd_task , fd_sum
740
814
if args .filter_tasks :
741
815
args .filter_tasks = args .filter_tasks .split ("," )
742
816
if args .limit_to_tasks :
@@ -769,6 +843,21 @@ def _argument_prepare_check():
769
843
time_unit = "ms"
770
844
771
845
846
+ fd_task = sys .stdout
847
+ if args .csv :
848
+ args .stdio_color = "never"
849
+ fd_task = open (args .csv , "w" )
850
+ print ("generating csv at" ,args .csv ,)
851
+
852
+ fd_sum = sys .stdout
853
+ if args .csv_summary :
854
+ args .stdio_color = "never"
855
+ fd_sum = open (args .csv_summary , "w" )
856
+ print ("generating csv summary at" ,args .csv_summary )
857
+ if not args .csv :
858
+ args .summary_only = True
859
+
860
+
772
861
def _is_within_timelimit (time ):
773
862
"""
774
863
Check if a time limit was given by parameter, if so ignore the rest. If not,
@@ -801,10 +890,17 @@ def _prepare_fmt_precision():
801
890
decimal_precision = 6
802
891
time_precision = 3
803
892
if args .ns :
804
- decimal_precision = 9
805
- time_precision = 0
893
+ decimal_precision = 9
894
+ time_precision = 0
806
895
return decimal_precision , time_precision
807
896
897
+ def _prepare_fmt_sep ():
898
+ separator = " "
899
+ fix_csv_align = 1
900
+ if args .csv or args .csv_summary :
901
+ separator = ";"
902
+ fix_csv_align = 0
903
+ return separator , fix_csv_align
808
904
809
905
def trace_unhandled (event_name , context , event_fields_dict , perf_sample_dict ):
810
906
pass
0 commit comments