func (this *Zktop) displayZoneTop(zkzone *zk.ZkZone) { if this.batchMode { this.Ui.Output(fmt.Sprintf("%s %s", zkzone.Name(), bjtime.NowBj())) } else { this.Ui.Output(color.Green(zkzone.Name())) } header := "VER SERVER PORT M OUTST RECVD SENT CONNS ZNODES LAT(MIN/AVG/MAX)" this.Ui.Output(header) stats := zkzone.RunZkFourLetterCommand("stat") sortedHosts := make([]string, 0, len(stats)) for hp, _ := range stats { sortedHosts = append(sortedHosts, hp) } sort.Strings(sortedHosts) for _, hostPort := range sortedHosts { host, port, err := net.SplitHostPort(hostPort) if err != nil { panic(err) } stat := zk.ParseStatResult(stats[hostPort]) if stat.Mode == "" { if this.batchMode { stat.Mode = "E" } else { stat.Mode = color.Red("E") } } else if stat.Mode == "L" && !this.batchMode { stat.Mode = color.Blue(stat.Mode) } var sentQps, recvQps int if lastRecv, present := this.lastRecvs[hostPort]; present { r1, _ := strconv.Atoi(stat.Received) r0, _ := strconv.Atoi(lastRecv) recvQps = (r1 - r0) / int(this.refreshInterval.Seconds()) s1, _ := strconv.Atoi(stat.Sent) s0, _ := strconv.Atoi(this.lastSents[hostPort]) sentQps = (s1 - s0) / int(this.refreshInterval.Seconds()) } this.Ui.Output(fmt.Sprintf("%-15s %-15s %5s %1s %6s %16s %16s %5s %7s %s", stat.Version, // 15 host, // 15 port, // 5 stat.Mode, // 1 stat.Outstanding, // 6 fmt.Sprintf("%s/%d", stat.Received, recvQps), // 16 fmt.Sprintf("%s/%d", stat.Sent, sentQps), // 16 stat.Connections, // 5 stat.Znodes, // 7 stat.Latency, )) this.lastRecvs[hostPort] = stat.Received this.lastSents[hostPort] = stat.Sent } }
func (this *Zookeeper) printLeader(zkzone *zk.ZkZone) { // FIXME all zones will only show the 1st zone info because it blocks others for { this.Ui.Output(color.Blue(zkzone.Name())) for zkhost, lines := range zkzone.RunZkFourLetterCommand("mntr") { if this.zkHost != "" && !strings.HasPrefix(zkhost, this.zkHost+":") { continue } parts := strings.Split(lines, "\n") for _, l := range parts { if strings.HasPrefix(l, "zk_server_state") && strings.HasSuffix(l, "leader") { this.Ui.Output(color.Green("%28s", zkhost)) break } } } if this.watchMode { time.Sleep(time.Second * 5) } else { break } } }
func NewSubStore(closedConnCh <-chan string, debug bool) *subStore { if debug { sarama.Logger = l.New(os.Stdout, color.Blue("[Sarama]"), l.LstdFlags|l.Lshortfile) } return &subStore{ hostname: ctx.Hostname(), shutdownCh: make(chan struct{}), closedConnCh: closedConnCh, } }
func (this *Zookeeper) printZkStats(zkzone *zk.ZkZone) { for { this.Ui.Output(color.Blue(zkzone.Name())) for zkhost, lines := range zkzone.RunZkFourLetterCommand(this.flw) { if this.zkHost != "" && !strings.HasPrefix(zkhost, this.zkHost+":") { continue } this.Ui.Output(fmt.Sprintf("%s\n%s", color.Green("%28s", zkhost), lines)) } if this.watchMode { time.Sleep(time.Second * 5) } else { break } } }
func (this *Consumers) printConsumersByHost(zkzone *zk.ZkZone, clusterPattern string) { outputs := make(map[string]map[string]map[string]int) // host: {cluster: {topic: count}} this.Ui.Output(color.Blue(zkzone.Name())) zkzone.ForSortedClusters(func(zkcluster *zk.ZkCluster) { if !patternMatched(zkcluster.Name(), clusterPattern) { return } consumerGroups := zkcluster.ConsumerGroups() for _, group := range consumerGroups { for _, c := range group { if _, present := outputs[c.Host()]; !present { outputs[c.Host()] = make(map[string]map[string]int) } if _, present := outputs[c.Host()][zkcluster.Name()]; !present { outputs[c.Host()][zkcluster.Name()] = make(map[string]int) } for topic, count := range c.Subscription { outputs[c.Host()][zkcluster.Name()][topic] += count } } } }) sortedHosts := make([]string, 0, len(outputs)) for host, _ := range outputs { sortedHosts = append(sortedHosts, host) } sort.Strings(sortedHosts) for _, host := range sortedHosts { tc := outputs[host] this.Ui.Output(fmt.Sprintf("%s %+v", color.Green("%22s", host), tc)) } }
func (c *Cluster) debug(format string, v ...interface{}) { if c.logLevel <= LogLevelDebug { pc, file, line, ok := runtime.Caller(1) if !ok { file = "<?>" line = 0 } else { if i := strings.LastIndex(file, "/"); i >= 0 { file = file[i+1:] } } fn := runtime.FuncForPC(pc).Name() fnparts := strings.Split(fn, "/") t := time.Now() hour, min, sec := t.Clock() nanosec := t.Nanosecond() / 1e3 debugLock.Lock() var nodePrefix string = c.self.ID.String() switch c.color { case "red": nodePrefix = color.Red(c.self.ID.String()) case "blue": nodePrefix = color.Blue(c.self.ID.String()) case "yellow": nodePrefix = color.Yellow(c.self.ID.String()) case "green": nodePrefix = color.Green(c.self.ID.String()) } fmt.Printf(nodePrefix+" [%d:%d:%d.%04d] %s:%d(%s): %s\n", hour, min, sec, nanosec, file, line, color.Red(fnparts[len(fnparts)-1]), fmt.Sprintf(format, v...)) debugLock.Unlock() } }
func (this *Lags) printConsumersLag(zkcluster *zk.ZkCluster) { // sort by group name consumersByGroup := zkcluster.ConsumersByGroup(this.groupPattern) sortedGroups := make([]string, 0, len(consumersByGroup)) for group, _ := range consumersByGroup { sortedGroups = append(sortedGroups, group) } sort.Strings(sortedGroups) for _, group := range sortedGroups { lines := make([]string, 0, 100) sortedTopicAndPartitionIds := make([]string, 0) consumers := make(map[string]zk.ConsumerMeta) for _, t := range consumersByGroup[group] { key := fmt.Sprintf("%s:%s", t.Topic, t.PartitionId) sortedTopicAndPartitionIds = append(sortedTopicAndPartitionIds, key) consumers[key] = t } sort.Strings(sortedTopicAndPartitionIds) for _, topicAndPartitionId := range sortedTopicAndPartitionIds { consumer := consumers[topicAndPartitionId] if !patternMatched(consumer.Topic, this.topicPattern) { continue } var ( lagOutput string symbol string ) if consumer.Lag > int64(this.lagThreshold) { lagOutput = color.Red("%15s", gofmt.Comma(consumer.Lag)) if consumer.Online { symbol = color.Yellow("⚠︎︎") } else { symbol = color.Yellow("◎") } } else { lagOutput = color.Blue("%15s", gofmt.Comma(consumer.Lag)) if consumer.Online { symbol = color.Green("◉") } else { symbol = color.Yellow("◎") } } if consumer.Online { if this.problematicMode && consumer.Lag <= int64(this.lagThreshold) { continue } var ( host string uptime string ) if consumer.ConsumerZnode == nil { host = "unrecognized" uptime = "-" } else { host = color.Green("%s", consumer.ConsumerZnode.Host()) if time.Since(consumer.ConsumerZnode.Uptime()) < time.Hour { uptime = color.Magenta(gofmt.PrettySince(consumer.ConsumerZnode.Uptime())) } else { uptime = gofmt.PrettySince(consumer.ConsumerZnode.Uptime()) } } lines = append(lines, fmt.Sprintf("\t%s %35s/%-2s %12s -> %-15s %s %-10s %s %s", symbol, consumer.Topic, consumer.PartitionId, gofmt.Comma(consumer.ProducerOffset), gofmt.Comma(consumer.ConsumerOffset), lagOutput, gofmt.PrettySince(consumer.Mtime.Time()), host, uptime)) } else if !this.onlineOnly { lines = append(lines, fmt.Sprintf("\t%s %35s/%-2s %12s -> %-12s %s %s", symbol, consumer.Topic, consumer.PartitionId, gofmt.Comma(consumer.ProducerOffset), gofmt.Comma(consumer.ConsumerOffset), lagOutput, gofmt.PrettySince(consumer.Mtime.Time()))) } } if len(lines) > 0 { this.Ui.Output(strings.Repeat(" ", 4) + group) for _, l := range lines { this.Ui.Output(l) } } } }
func (this *Consumers) cleanupStaleConsumerGroups(zkzone *zk.ZkZone, clusterPattern string) { // what consumer groups are safe to delete? // 1. not online // 2. have no offsets this.Ui.Output(color.Blue(zkzone.Name())) zkzone.ForSortedClusters(func(zkcluster *zk.ZkCluster) { if !patternMatched(zkcluster.Name(), clusterPattern) { return } this.Ui.Output(strings.Repeat(" ", 4) + zkcluster.Name()) consumerGroups := zkcluster.ConsumerGroups() for group, consumers := range consumerGroups { if len(consumers) > 0 { // this consumer group is online continue } if !patternMatched(group, this.groupPattern) { continue } if !strings.HasPrefix(group, "console-consumer-") { path := zkcluster.ConsumerGroupOffsetPath(group) _, _, err := zkzone.Conn().Children(path) if err == nil { this.Ui.Warn(fmt.Sprintf("%s not empty, unsafe to cleanup", path)) continue } if err != gozk.ErrNoNode { // should never happen swallow(err) } } // have no offsets, safe to delete if this.confirmYes { yes, err := this.Ui.Ask(fmt.Sprintf("confirm to remove cluster[%s] consumer group: %s? [Y/n]", zkcluster.Name(), group)) swallow(err) if strings.ToLower(yes) == "n" { this.Ui.Info(fmt.Sprintf("%s skipped", group)) continue } } else { yes, err := this.Ui.Ask(fmt.Sprintf("confirm to remove cluster[%s] consumer group: %s? [y/N]", zkcluster.Name(), group)) swallow(err) if strings.ToLower(yes) != "y" { this.Ui.Info(fmt.Sprintf("%s skipped", group)) continue } } // do delete this consumer group zkzone.DeleteRecursive(zkcluster.ConsumerGroupRoot(group)) this.Ui.Info(fmt.Sprintf("%s deleted", group)) } }) }