Skip to content

Commit

Permalink
Merge pull request #10782 from jingyih/cherrypick_9540_to_release3p3
Browse files Browse the repository at this point in the history
ctlv3: cherry pick of #9540 to release 3.3
  • Loading branch information
gyuho authored Jun 4, 2019
2 parents b0babe5 + f835a85 commit 8942970
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 8 deletions.
28 changes: 20 additions & 8 deletions etcdctl/ctlv3/command/ep_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,17 @@ func newEpHashKVCommand() *cobra.Command {
return hc
}

type epHealth struct {
Ep string `json:"endpoint"`
Health bool `json:"health"`
Took string `json:"took"`
Error string `json:"error,omitempty"`
}

// epHealthCommandFunc executes the "endpoint-health" command.
func epHealthCommandFunc(cmd *cobra.Command, args []string) {
flags.SetPflagsFromEnv("ETCDCTL", cmd.InheritedFlags())
initDisplayFromCmd(cmd)

sec := secureCfgFromCmd(cmd)
dt := dialTimeoutFromCmd(cmd)
Expand All @@ -95,15 +103,15 @@ func epHealthCommandFunc(cmd *cobra.Command, args []string) {
}

var wg sync.WaitGroup
errc := make(chan error, len(cfgs))
hch := make(chan epHealth, len(cfgs))
for _, cfg := range cfgs {
wg.Add(1)
go func(cfg *v3.Config) {
defer wg.Done()
ep := cfg.Endpoints[0]
cli, err := v3.New(*cfg)
if err != nil {
errc <- fmt.Errorf("%s is unhealthy: failed to connect: %v", ep, err)
hch <- epHealth{Ep: ep, Health: false, Error: err.Error()}
return
}
st := time.Now()
Expand All @@ -112,25 +120,29 @@ func epHealthCommandFunc(cmd *cobra.Command, args []string) {
ctx, cancel := commandCtx(cmd)
_, err = cli.Get(ctx, "health")
cancel()
eh := epHealth{Ep: ep, Health: false, Took: time.Since(st).String()}
// permission denied is OK since proposal goes through consensus to get it
if err == nil || err == rpctypes.ErrPermissionDenied {
fmt.Printf("%s is healthy: successfully committed proposal: took = %v\n", ep, time.Since(st))
eh.Health = true
} else {
errc <- fmt.Errorf("%s is unhealthy: failed to commit proposal: %v", ep, err)
eh.Error = err.Error()
}
hch <- eh
}(cfg)
}

wg.Wait()
close(errc)
close(hch)

errs := false
for err := range errc {
if err != nil {
healthList := []epHealth{}
for h := range hch {
healthList = append(healthList, h)
if h.Error != "" {
errs = true
fmt.Fprintln(os.Stderr, err)
}
}
display.EndpointHealth(healthList)
if errs {
ExitWithError(ExitError, fmt.Errorf("unhealthy cluster"))
}
Expand Down
15 changes: 15 additions & 0 deletions etcdctl/ctlv3/command/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type printer interface {
MemberUpdate(id uint64, r v3.MemberUpdateResponse)
MemberList(v3.MemberListResponse)

EndpointHealth([]epHealth)
EndpointStatus([]epStatus)
EndpointHashKV([]epHashKV)
MoveLeader(leader, target uint64, r v3.MoveLeaderResponse)
Expand Down Expand Up @@ -148,6 +149,7 @@ func newPrinterUnsupported(n string) printer {
return &printerUnsupported{printerRPC{nil, f}}
}

func (p *printerUnsupported) EndpointHealth([]epHealth) { p.p(nil) }
func (p *printerUnsupported) EndpointStatus([]epStatus) { p.p(nil) }
func (p *printerUnsupported) EndpointHashKV([]epHashKV) { p.p(nil) }
func (p *printerUnsupported) DBStatus(dbstatus) { p.p(nil) }
Expand All @@ -172,6 +174,19 @@ func makeMemberListTable(r v3.MemberListResponse) (hdr []string, rows [][]string
return hdr, rows
}

func makeEndpointHealthTable(healthList []epHealth) (hdr []string, rows [][]string) {
hdr = []string{"endpoint", "health", "took", "error"}
for _, h := range healthList {
rows = append(rows, []string{
h.Ep,
fmt.Sprintf("%v", h.Health),
h.Took,
h.Error,
})
}
return hdr, rows
}

func makeEndpointStatusTable(statusList []epStatus) (hdr []string, rows [][]string) {
hdr = []string{"endpoint", "ID", "version", "db size", "is leader", "raft term", "raft index"}
for _, status := range statusList {
Expand Down
10 changes: 10 additions & 0 deletions etcdctl/ctlv3/command/printer_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ func (p *fieldsPrinter) MemberList(r v3.MemberListResponse) {
}
}

func (p *fieldsPrinter) EndpointHealth(hs []epHealth) {
for _, h := range hs {
fmt.Printf("\"Endpoint\" : %q\n", h.Ep)
fmt.Println(`"Health" :`, h.Health)
fmt.Println(`"Took" :`, h.Took)
fmt.Println(`"Error" :`, h.Error)
fmt.Println()
}
}

func (p *fieldsPrinter) EndpointStatus(eps []epStatus) {
for _, ep := range eps {
p.hdr(ep.Resp.Header)
Expand Down
1 change: 1 addition & 0 deletions etcdctl/ctlv3/command/printer_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func newJSONPrinter() printer {
}
}

func (p *jsonPrinter) EndpointHealth(r []epHealth) { printJSON(r) }
func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) }
func (p *jsonPrinter) EndpointHashKV(r []epHashKV) { printJSON(r) }
func (p *jsonPrinter) DBStatus(r dbstatus) { printJSON(r) }
Expand Down
11 changes: 11 additions & 0 deletions etcdctl/ctlv3/command/printer_simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package command

import (
"fmt"
"os"
"strings"

v3 "github.com/coreos/etcd/clientv3"
Expand Down Expand Up @@ -141,6 +142,16 @@ func (s *simplePrinter) MemberList(resp v3.MemberListResponse) {
}
}

func (s *simplePrinter) EndpointHealth(hs []epHealth) {
for _, h := range hs {
if h.Error == "" {
fmt.Fprintf(os.Stderr, "%s is healthy: successfully committed proposal: took = %v\n", h.Ep, h.Took)
} else {
fmt.Fprintf(os.Stderr, "%s is unhealthy: failed to commit proposal: %v", h.Ep, h.Error)
}
}
}

func (s *simplePrinter) EndpointStatus(statusList []epStatus) {
_, rows := makeEndpointStatusTable(statusList)
for _, row := range rows {
Expand Down
10 changes: 10 additions & 0 deletions etcdctl/ctlv3/command/printer_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ func (tp *tablePrinter) MemberList(r v3.MemberListResponse) {
table.SetAlignment(tablewriter.ALIGN_RIGHT)
table.Render()
}
func (tp *tablePrinter) EndpointHealth(r []epHealth) {
hdr, rows := makeEndpointHealthTable(r)
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader(hdr)
for _, row := range rows {
table.Append(row)
}
table.SetAlignment(tablewriter.ALIGN_RIGHT)
table.Render()
}
func (tp *tablePrinter) EndpointStatus(r []epStatus) {
hdr, rows := makeEndpointStatusTable(r)
table := tablewriter.NewWriter(os.Stdout)
Expand Down

0 comments on commit 8942970

Please sign in to comment.