github.com/streamdal/segmentio-kafka-go@v0.4.47-streamdal/protocol/cluster.go (about) 1 package protocol 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 "text/tabwriter" 8 ) 9 10 type Cluster struct { 11 ClusterID string 12 Controller int32 13 Brokers map[int32]Broker 14 Topics map[string]Topic 15 } 16 17 func (c Cluster) BrokerIDs() []int32 { 18 brokerIDs := make([]int32, 0, len(c.Brokers)) 19 for id := range c.Brokers { 20 brokerIDs = append(brokerIDs, id) 21 } 22 sort.Slice(brokerIDs, func(i, j int) bool { 23 return brokerIDs[i] < brokerIDs[j] 24 }) 25 return brokerIDs 26 } 27 28 func (c Cluster) TopicNames() []string { 29 topicNames := make([]string, 0, len(c.Topics)) 30 for name := range c.Topics { 31 topicNames = append(topicNames, name) 32 } 33 sort.Strings(topicNames) 34 return topicNames 35 } 36 37 func (c Cluster) IsZero() bool { 38 return c.ClusterID == "" && c.Controller == 0 && len(c.Brokers) == 0 && len(c.Topics) == 0 39 } 40 41 func (c Cluster) Format(w fmt.State, _ rune) { 42 tw := new(tabwriter.Writer) 43 fmt.Fprintf(w, "CLUSTER: %q\n\n", c.ClusterID) 44 45 tw.Init(w, 0, 8, 2, ' ', 0) 46 fmt.Fprint(tw, " BROKER\tHOST\tPORT\tRACK\tCONTROLLER\n") 47 48 for _, id := range c.BrokerIDs() { 49 broker := c.Brokers[id] 50 fmt.Fprintf(tw, " %d\t%s\t%d\t%s\t%t\n", broker.ID, broker.Host, broker.Port, broker.Rack, broker.ID == c.Controller) 51 } 52 53 tw.Flush() 54 fmt.Fprintln(w) 55 56 tw.Init(w, 0, 8, 2, ' ', 0) 57 fmt.Fprint(tw, " TOPIC\tPARTITIONS\tBROKERS\n") 58 topicNames := c.TopicNames() 59 brokers := make(map[int32]struct{}, len(c.Brokers)) 60 brokerIDs := make([]int32, 0, len(c.Brokers)) 61 62 for _, name := range topicNames { 63 topic := c.Topics[name] 64 65 for _, p := range topic.Partitions { 66 for _, id := range p.Replicas { 67 brokers[id] = struct{}{} 68 } 69 } 70 71 for id := range brokers { 72 brokerIDs = append(brokerIDs, id) 73 } 74 75 fmt.Fprintf(tw, " %s\t%d\t%s\n", topic.Name, len(topic.Partitions), formatBrokerIDs(brokerIDs, -1)) 76 77 for id := range brokers { 78 delete(brokers, id) 79 } 80 81 brokerIDs = brokerIDs[:0] 82 } 83 84 tw.Flush() 85 fmt.Fprintln(w) 86 87 if w.Flag('+') { 88 for _, name := range topicNames { 89 fmt.Fprintf(w, " TOPIC: %q\n\n", name) 90 91 tw.Init(w, 0, 8, 2, ' ', 0) 92 fmt.Fprint(tw, " PARTITION\tREPLICAS\tISR\tOFFLINE\n") 93 94 for _, p := range c.Topics[name].Partitions { 95 fmt.Fprintf(tw, " %d\t%s\t%s\t%s\n", p.ID, 96 formatBrokerIDs(p.Replicas, -1), 97 formatBrokerIDs(p.ISR, p.Leader), 98 formatBrokerIDs(p.Offline, -1), 99 ) 100 } 101 102 tw.Flush() 103 fmt.Fprintln(w) 104 } 105 } 106 } 107 108 func formatBrokerIDs(brokerIDs []int32, leader int32) string { 109 if len(brokerIDs) == 0 { 110 return "" 111 } 112 113 if len(brokerIDs) == 1 { 114 return itoa(brokerIDs[0]) 115 } 116 117 sort.Slice(brokerIDs, func(i, j int) bool { 118 id1 := brokerIDs[i] 119 id2 := brokerIDs[j] 120 121 if id1 == leader { 122 return true 123 } 124 125 if id2 == leader { 126 return false 127 } 128 129 return id1 < id2 130 }) 131 132 brokerNames := make([]string, len(brokerIDs)) 133 134 for i, id := range brokerIDs { 135 brokerNames[i] = itoa(id) 136 } 137 138 return strings.Join(brokerNames, ",") 139 } 140 141 var ( 142 _ fmt.Formatter = Cluster{} 143 )