From 5e2c2a4cdf5b92b084024248f448226c0db80824 Mon Sep 17 00:00:00 2001 From: Neil Twigg Date: Tue, 26 Sep 2023 10:08:12 +0100 Subject: [PATCH] Report observer status in cluster replicas for streams and consumers This is to support nats-io/nats-server#4582. Signed-off-by: Neil Twigg --- cli/consumer_command.go | 11 +-------- cli/kv_command.go | 4 ++++ cli/stream_command.go | 28 +---------------------- cli/util.go | 49 ++++++++++++++++++++++++++++++++++++++--- go.mod | 11 +++++---- go.sum | 12 ++++------ 6 files changed, 63 insertions(+), 52 deletions(-) diff --git a/cli/consumer_command.go b/cli/consumer_command.go index 4cbb7464..899946eb 100644 --- a/cli/consumer_command.go +++ b/cli/consumer_command.go @@ -637,16 +637,7 @@ func (c *consumerCmd) showInfo(config api.ConsumerConfig, state api.ConsumerInfo cols.AddRow("Name", state.Cluster.Name) cols.AddRow("Leader", state.Cluster.Leader) for _, r := range state.Cluster.Replicas { - since := fmt.Sprintf("seen %s ago", f(r.Active)) - if r.Active == 0 || r.Active == math.MaxInt64 { - since = "not seen" - } - - if r.Current { - cols.AddRowf("Replica", "%s, current, %s", r.Name, since) - } else { - cols.AddRowf("Replica", "%s, outdated, %s", r.Name, since) - } + cols.AddRow("Replica", replicaInfoFor(r)) } } diff --git a/cli/kv_command.go b/cli/kv_command.go index cacc1d0b..bc4a628e 100644 --- a/cli/kv_command.go +++ b/cli/kv_command.go @@ -838,6 +838,10 @@ func renderNatsGoClusterInfo(cols *columns.Writer, info *nats.StreamInfo) { state = append(state, "outdated") } + if r.Observer { + state = append(state, "observer") + } + if r.Offline { state = append(state, "OFFLINE") } diff --git a/cli/stream_command.go b/cli/stream_command.go index 377db918..bb167e45 100644 --- a/cli/stream_command.go +++ b/cli/stream_command.go @@ -1933,33 +1933,7 @@ func (c *streamCmd) showStreamInfo(info *api.StreamInfo) { cols.AddRow("Name", info.Cluster.Name) cols.AddRow("Leader", info.Cluster.Leader) for _, r := range info.Cluster.Replicas { - state := []string{r.Name} - - if r.Current { - state = append(state, "current") - } else { - state = append(state, "outdated") - } - - if r.Offline { - state = append(state, "OFFLINE") - } - - if r.Active > 0 && r.Active < math.MaxInt64 { - state = append(state, fmt.Sprintf("seen %s ago", f(r.Active))) - } else { - state = append(state, "not seen") - } - - switch { - case r.Lag > 1: - state = append(state, fmt.Sprintf("%s operations behind", f(r.Lag))) - case r.Lag == 1: - state = append(state, fmt.Sprintf("%s operation behind", f(r.Lag))) - } - - cols.AddRow("Replica", state) - + cols.AddRow("Replica", replicaInfoFor(r)) } cols.Println() } diff --git a/cli/util.go b/cli/util.go index caedc311..ad142fa5 100644 --- a/cli/util.go +++ b/cli/util.go @@ -789,8 +789,9 @@ func renderCluster(cluster *api.ClusterInfo) string { // first we figure out leader and downs based on the full names and build // peers array which is a list of all the full names leader := -1 - warn := []int{} - var peers []string + peers := make([]string, 0, len(cluster.Replicas)) + warn := make([]int, 0, len(cluster.Replicas)) + obs := make([]int, 0, len(cluster.Replicas)) if cluster.Leader != "" { peers = append(peers, cluster.Leader) @@ -805,7 +806,13 @@ func renderCluster(cluster *api.ClusterInfo) string { } else { warn = append(warn, i) } - + } + if r.Observer { + if leader == 0 { + obs = append(obs, i+1) + } else { + obs = append(obs, i) + } } peers = append(peers, name) } @@ -815,6 +822,9 @@ func renderCluster(cluster *api.ClusterInfo) string { if leader != -1 { compact[0] = compact[0] + "*" } + for _, i := range obs { + compact[i] = compact[i] + "^" + } for _, i := range warn { compact[i] = compact[i] + "!" } @@ -1360,3 +1370,36 @@ func structWithoutOmitEmpty(s any) any { return res } + +func replicaInfoFor(r *api.PeerInfo) []string { + state := []string{r.Name} + + if r.Current { + state = append(state, "current") + } else { + state = append(state, "outdated") + } + + if r.Observer { + state = append(state, "observer") + } + + if r.Offline { + state = append(state, "OFFLINE") + } + + if r.Active > 0 && r.Active < math.MaxInt64 { + state = append(state, fmt.Sprintf("seen %s ago", f(r.Active))) + } else { + state = append(state, "not seen") + } + + switch { + case r.Lag > 1: + state = append(state, fmt.Sprintf("%s operations behind", f(r.Lag))) + case r.Lag == 1: + state = append(state, fmt.Sprintf("%s operation behind", f(r.Lag))) + } + + return state +} diff --git a/go.mod b/go.mod index 75e6b7e6..42b5bb41 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,14 @@ module github.com/nats-io/natscli go 1.20 +replace github.com/nats-io/jsm.go => github.com/nats-io/jsm.go v0.1.1-0.20230926090317-6fb84b8ef01d + +replace github.com/nats-io/nats.go => github.com/nats-io/nats.go v1.30.2-0.20230926090553-22cd46b4d288 + require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/HdrHistogram/hdrhistogram-go v1.1.2 + github.com/antonmedv/expr v1.15.3 github.com/choria-io/fisk v0.6.0 github.com/dustin/go-humanize v1.0.1 github.com/emicklei/dot v1.6.0 @@ -19,8 +24,10 @@ require ( github.com/klauspost/compress v1.17.0 github.com/mattn/go-isatty v0.0.19 github.com/nats-io/jsm.go v0.1.1-0.20230922064108-bb09405bc2c0 + github.com/nats-io/jwt/v2 v2.5.2 github.com/nats-io/nats-server/v2 v2.10.1 github.com/nats-io/nats.go v1.30.0 + github.com/nats-io/nkeys v0.4.5 github.com/nats-io/nuid v1.0.1 github.com/prometheus/client_golang v1.16.0 github.com/prometheus/common v0.44.0 @@ -32,7 +39,6 @@ require ( ) require ( - github.com/antonmedv/expr v1.15.3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -42,12 +48,9 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/minio/highwayhash v1.0.2 // indirect - github.com/nats-io/jwt/v2 v2.5.2 // indirect - github.com/nats-io/nkeys v0.4.5 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/sevlyar/retag v0.0.0-20190429052747-c3f10e304082 // indirect golang.org/x/net v0.15.0 // indirect golang.org/x/sys v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect diff --git a/go.sum b/go.sum index 61f5dda9..a4805a3e 100644 --- a/go.sum +++ b/go.sum @@ -80,16 +80,14 @@ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= -github.com/nats-io/jsm.go v0.1.1-0.20230921074448-1bbb5650afc8 h1:OKm9e1//rlcl4i9zXQ6QQxj7DJaeL+Oe8WBgAKO4cqI= -github.com/nats-io/jsm.go v0.1.1-0.20230921074448-1bbb5650afc8/go.mod h1:hB4Qd+IKoRvAAWTOI1HkCy4wotjFwOIT+codHCFOZqk= -github.com/nats-io/jsm.go v0.1.1-0.20230922064108-bb09405bc2c0 h1:YrGcddIEq3vsWFO6JKGqHF1NquZCCKXJBJmp61tDRJY= -github.com/nats-io/jsm.go v0.1.1-0.20230922064108-bb09405bc2c0/go.mod h1:hB4Qd+IKoRvAAWTOI1HkCy4wotjFwOIT+codHCFOZqk= +github.com/nats-io/jsm.go v0.1.1-0.20230926090317-6fb84b8ef01d h1:jHy988Qmc1KRJjnyMoAHqMfZYtFFGhV8mh0EsMrh+DE= +github.com/nats-io/jsm.go v0.1.1-0.20230926090317-6fb84b8ef01d/go.mod h1:hB4Qd+IKoRvAAWTOI1HkCy4wotjFwOIT+codHCFOZqk= github.com/nats-io/jwt/v2 v2.5.2 h1:DhGH+nKt+wIkDxM6qnVSKjokq5t59AZV5HRcFW0zJwU= github.com/nats-io/jwt/v2 v2.5.2/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI= github.com/nats-io/nats-server/v2 v2.10.1 h1:MIJ614dhOIdo71iSzY8ln78miXwrYvlvXHUyS+XdKZQ= github.com/nats-io/nats-server/v2 v2.10.1/go.mod h1:3PMvMSu2cuK0J9YInRLWdFpFsswKKGUS77zVSAudRto= -github.com/nats-io/nats.go v1.30.0 h1:bj/rVsRCrFXxmm9mJiDhb74UKl2HhKpDwKRBtvCjZjc= -github.com/nats-io/nats.go v1.30.0/go.mod h1:dcfhUgmQNN4GJEfIb2f9R7Fow+gzBF4emzDHrVBd5qM= +github.com/nats-io/nats.go v1.30.2-0.20230926090553-22cd46b4d288 h1:ZF1eeVI+Tkmd9Ks9QB+OXt/NLuPv+mXKxiu7nixTmVU= +github.com/nats-io/nats.go v1.30.2-0.20230926090553-22cd46b4d288/go.mod h1:dcfhUgmQNN4GJEfIb2f9R7Fow+gzBF4emzDHrVBd5qM= github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk= github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= @@ -112,8 +110,6 @@ github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= -github.com/sevlyar/retag v0.0.0-20190429052747-c3f10e304082 h1:fj05fHX+p6w6xqPfvEjFtdu95JwguF0Kg1cz/sht8+U= -github.com/sevlyar/retag v0.0.0-20190429052747-c3f10e304082/go.mod h1:mOWh3Kdot9kBKCLbKcJTzIBBEPKRJAq2lk03eVVDmco= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=