@@ -504,6 +504,205 @@ func FormatTopicPartitions(partitions []PartitionInfo, brokers []BrokerInfo) str
504
504
return string (bytes .TrimRight (buf .Bytes (), "\n " ))
505
505
}
506
506
507
+ // FormatTopicsPartitionsSummary creates a pretty table with summary of the
508
+ // partitions for topics.
509
+ func FormatTopicsPartitionsSummary (
510
+ topicsPartitionsStatusSummary map [string ]map [PartitionStatus ][]int ,
511
+ ) string {
512
+ buf := & bytes.Buffer {}
513
+
514
+ headers := []string {
515
+ "Topic" ,
516
+ "Status" ,
517
+ "Count" ,
518
+ "IDs" ,
519
+ }
520
+ columnAligment := []int {
521
+ tablewriter .ALIGN_LEFT ,
522
+ tablewriter .ALIGN_LEFT ,
523
+ tablewriter .ALIGN_LEFT ,
524
+ tablewriter .ALIGN_LEFT ,
525
+ }
526
+
527
+ table := tablewriter .NewWriter (buf )
528
+ table .SetHeader (headers )
529
+ table .SetAutoWrapText (true )
530
+ table .SetColumnAlignment (columnAligment )
531
+ table .SetBorders (
532
+ tablewriter.Border {
533
+ Left : false ,
534
+ Top : true ,
535
+ Right : false ,
536
+ Bottom : true ,
537
+ },
538
+ )
539
+
540
+ topicNames := []string {}
541
+ tableData := make (map [string ][][]string )
542
+ for topicName , partitionsStatusSummary := range topicsPartitionsStatusSummary {
543
+ topicTableRows := [][]string {}
544
+
545
+ for partitionStatus , partitionStatusIDs := range partitionsStatusSummary {
546
+ topicTableRows = append (topicTableRows , []string {
547
+ fmt .Sprintf ("%s" , topicName ),
548
+ fmt .Sprintf ("%s" , partitionStatus ),
549
+ fmt .Sprintf ("%d" , len (partitionStatusIDs )),
550
+ fmt .Sprintf ("%+v" , partitionStatusIDs ),
551
+ })
552
+ }
553
+
554
+ // sort the topicTableRows by partitionStatus
555
+ statusSort := func (i , j int ) bool {
556
+ // second element in the row is of type PartitionStatus
557
+ return string (topicTableRows [i ][1 ]) < string (topicTableRows [j ][1 ])
558
+ }
559
+
560
+ sort .Slice (topicTableRows , statusSort )
561
+
562
+ tableData [topicName ] = topicTableRows
563
+ topicNames = append (topicNames , topicName )
564
+ }
565
+
566
+ sort .Strings (topicNames )
567
+ for _ , topicName := range topicNames {
568
+ _ , exists := tableData [topicName ]
569
+ if exists {
570
+ for _ , topicTableRow := range tableData [topicName ] {
571
+ table .Append (topicTableRow )
572
+ }
573
+ }
574
+ }
575
+
576
+ table .Render ()
577
+ return string (bytes .TrimRight (buf .Bytes (), "\n " ))
578
+ }
579
+
580
+ // FormatTopicsPartitions creates a pretty table with information on all of the
581
+ // partitions for topics.
582
+ func FormatTopicsPartitions (
583
+ topicsPartitionsStatusInfo map [string ][]PartitionStatusInfo ,
584
+ brokers []BrokerInfo ,
585
+ ) string {
586
+ buf := & bytes.Buffer {}
587
+
588
+ headers := []string {
589
+ "Topic" ,
590
+ "ID" ,
591
+ "Leader" ,
592
+ "ISR" ,
593
+ "Replicas" ,
594
+ "Distinct\n Racks" ,
595
+ "Racks" ,
596
+ "Status" ,
597
+ }
598
+ columnAligment := []int {
599
+ tablewriter .ALIGN_LEFT ,
600
+ tablewriter .ALIGN_LEFT ,
601
+ tablewriter .ALIGN_LEFT ,
602
+ tablewriter .ALIGN_LEFT ,
603
+ tablewriter .ALIGN_LEFT ,
604
+ tablewriter .ALIGN_LEFT ,
605
+ tablewriter .ALIGN_LEFT ,
606
+ tablewriter .ALIGN_LEFT ,
607
+ }
608
+
609
+ table := tablewriter .NewWriter (buf )
610
+ table .SetHeader (headers )
611
+ table .SetAutoWrapText (false )
612
+ table .SetColumnAlignment (columnAligment )
613
+ table .SetBorders (
614
+ tablewriter.Border {
615
+ Left : false ,
616
+ Top : true ,
617
+ Right : false ,
618
+ Bottom : true ,
619
+ },
620
+ )
621
+
622
+ topicNames := []string {}
623
+ brokerRacks := BrokerRacks (brokers )
624
+ tableData := make (map [string ][][]string )
625
+ for topicName , partitionsStatusInfo := range topicsPartitionsStatusInfo {
626
+ topicTableRows := [][]string {}
627
+ for _ , partitionStatusInfo := range partitionsStatusInfo {
628
+ racks := partitionStatusInfo .Racks (brokerRacks )
629
+
630
+ distinctRacks := make (map [string ]int )
631
+ for _ , rack := range racks {
632
+ distinctRacks [rack ] += 1
633
+ }
634
+
635
+ partitionIsrs := []int {}
636
+ for _ , partitionStatusIsr := range partitionStatusInfo .Partition .Isr {
637
+ partitionIsrs = append (partitionIsrs , partitionStatusIsr .ID )
638
+ }
639
+
640
+ partitionReplicas := []int {}
641
+ for _ , partitionReplica := range partitionStatusInfo .Partition .Replicas {
642
+ partitionReplicas = append (partitionReplicas , partitionReplica .ID )
643
+ }
644
+
645
+ inSync := true
646
+ if partitionStatusInfo .Status != Ok {
647
+ inSync = false
648
+ }
649
+
650
+ correctLeader := true
651
+ if partitionStatusInfo .LeaderState != CorrectLeader {
652
+ correctLeader = false
653
+ }
654
+
655
+ var statusPrinter func (f string , a ... interface {}) string
656
+ if ! util .InTerminal () || inSync {
657
+ statusPrinter = fmt .Sprintf
658
+ } else if ! inSync {
659
+ statusPrinter = color .New (color .FgRed ).SprintfFunc ()
660
+ }
661
+
662
+ var statePrinter func (f string , a ... interface {}) string
663
+ if ! util .InTerminal () || correctLeader {
664
+ statePrinter = fmt .Sprintf
665
+ } else if ! correctLeader {
666
+ statePrinter = color .New (color .FgCyan ).SprintfFunc ()
667
+ }
668
+
669
+ leaderStateString := fmt .Sprintf ("%d" , partitionStatusInfo .Partition .Leader .ID )
670
+ if ! correctLeader {
671
+ leaderStateString = fmt .Sprintf ("%d %+v" , partitionStatusInfo .Partition .Leader .ID ,
672
+ statePrinter ("(%s)" , string (partitionStatusInfo .LeaderState )),
673
+ )
674
+ }
675
+
676
+ topicTableRows = append (topicTableRows , []string {
677
+ fmt .Sprintf ("%s" , topicName ),
678
+ fmt .Sprintf ("%d" , partitionStatusInfo .Partition .ID ),
679
+ leaderStateString ,
680
+ fmt .Sprintf ("%+v" , partitionIsrs ),
681
+ fmt .Sprintf ("%+v" , partitionReplicas ),
682
+ fmt .Sprintf ("%d" , len (distinctRacks )),
683
+ fmt .Sprintf ("%+v" , racks ),
684
+ fmt .Sprintf ("%v" , statusPrinter ("%s" , string (partitionStatusInfo .Status ))),
685
+ })
686
+ }
687
+
688
+ tableData [topicName ] = topicTableRows
689
+ topicNames = append (topicNames , topicName )
690
+ }
691
+
692
+ sort .Strings (topicNames )
693
+ for _ , topicName := range topicNames {
694
+ _ , exists := tableData [topicName ]
695
+ if exists {
696
+ for _ , topicTableRow := range tableData [topicName ] {
697
+ table .Append (topicTableRow )
698
+ }
699
+ }
700
+ }
701
+
702
+ table .Render ()
703
+ return string (bytes .TrimRight (buf .Bytes (), "\n " ))
704
+ }
705
+
507
706
// FormatConfig creates a pretty table with all of the keys and values in a topic or
508
707
// broker config.
509
708
func FormatConfig (configMap map [string ]string ) string {
0 commit comments