123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package command
- import (
- "encoding/json"
- "fmt"
- "net/http"
- "os"
- "os/signal"
- "time"
- "github.com/coreos/etcd/Godeps/_workspace/src/github.com/codegangsta/cli"
- "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
- )
- func NewClusterHealthCommand() cli.Command {
- return cli.Command{
- Name: "cluster-health",
- Usage: "check the health of the etcd cluster",
- Flags: []cli.Flag{
- cli.BoolFlag{Name: "forever", Usage: "forever check the health every 10 second until CTRL+C"},
- },
- Action: handleClusterHealth,
- }
- }
- func handleClusterHealth(c *cli.Context) {
- forever := c.Bool("forever")
- if forever {
- sigch := make(chan os.Signal, 1)
- signal.Notify(sigch, os.Interrupt)
- go func() {
- <-sigch
- os.Exit(0)
- }()
- }
- tr, err := getTransport(c)
- if err != nil {
- handleError(ExitServerError, err)
- }
- hc := http.Client{
- Transport: tr,
- }
- mi := mustNewMembersAPI(c)
- ms, err := mi.List(context.TODO())
- if err != nil {
- fmt.Println("cluster may be unhealthy: failed to list members")
- handleError(ExitServerError, err)
- }
- for {
- health := false
- for _, m := range ms {
- checked := false
- for _, url := range m.ClientURLs {
- resp, err := hc.Get(url + "/health")
- if err != nil {
- fmt.Printf("failed to check the health of member %s on %s: %v\n", m.ID, url, err)
- continue
- }
- result := struct{ Health string }{}
- d := json.NewDecoder(resp.Body)
- err = d.Decode(&result)
- resp.Body.Close()
- if err != nil {
- fmt.Printf("failed to check the health of member %s on %s: %v\n", m.ID, url, err)
- continue
- }
- checked = true
- if result.Health == "true" {
- health = true
- fmt.Printf("member %s is healthy: got healthy result from %s\n", m.ID, url)
- } else {
- fmt.Printf("member %s is unhealthy: got unhealthy result from %s\n", m.ID, url)
- }
- break
- }
- if !checked {
- fmt.Printf("member %s is unreachable: %v are all unreachable\n", m.ID, m.ClientURLs)
- }
- }
- if health {
- fmt.Println("cluster is healthy")
- } else {
- fmt.Println("cluster is unhealthy")
- }
- if !forever {
- break
- }
- fmt.Printf("\nnext check after 10 second...\n\n")
- time.Sleep(10 * time.Second)
- }
- }
|