Skip to content

Commit

Permalink
Merge pull request #22 from github/update_cluster_health
Browse files Browse the repository at this point in the history
Change the type of the GetHealth API
  • Loading branch information
Nick Canzoneri authored Dec 19, 2018
2 parents c2a7aa1 + cde8296 commit 2f638f3
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 37 deletions.
22 changes: 10 additions & 12 deletions cmd/vulcanizer/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,20 @@ var cmdHealth = &cobra.Command{
os.Exit(1)
}

fmt.Println(health[0].Message)
fmt.Println(health.Message)

header := []string{"Cluster", "Status", "Relocating", "Initializing", "Unassigned", "Active %"}
rows := [][]string{}
for _, cluster := range health {
row := []string{
cluster.Cluster,
cluster.Status,
strconv.Itoa(cluster.RelocatingShards),
strconv.Itoa(cluster.InitializingShards),
strconv.Itoa(cluster.UnassignedShards),
cluster.ActiveShardsPercentage,
}

rows = append(rows, row)
row := []string{
health.Cluster,
health.Status,
strconv.Itoa(health.RelocatingShards),
strconv.Itoa(health.InitializingShards),
strconv.Itoa(health.UnassignedShards),
strconv.Itoa(health.UnassignedShards),
strconv.FormatFloat(health.ActiveShardsPercentage, 'f', -1, 32),
}
rows = append(rows, row)

fmt.Println(renderTable(rows, header))
},
Expand Down
49 changes: 35 additions & 14 deletions es.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,29 @@ type Index struct {
DocumentCount int `json:"docs.count,string"`
}

//Holds information about the health of an Elasticsearch cluster, based on the _cat/health API: https://www.elastic.co/guide/en/elasticsearch/reference/5.6/cat-health.html
//Holds information about the health of an Elasticsearch cluster, based on the cluster health API: https://www.elastic.co/guide/en/elasticsearch/reference/5.6/cluster-health.html
type ClusterHealth struct {
Cluster string `json:"cluster"`
Status string `json:"status"`
RelocatingShards int `json:"relo,string"`
InitializingShards int `json:"init,string"`
UnassignedShards int `json:"unassign,string"`
ActiveShardsPercentage string `json:"active_shards_percent"`
Cluster string `json:"cluster_name"`
Status string `json:"status"`
ActiveShards int `json:"active_shards"`
RelocatingShards int `json:"relocating_shards"`
InitializingShards int `json:"initializing_shards"`
UnassignedShards int `json:"unassigned_shards"`
ActiveShardsPercentage float64 `json:"active_shards_percent_as_number"`
Message string
RawIndices map[string]IndexHealth `json:"indices"`
HealthyIndices []IndexHealth
UnhealthyIndices []IndexHealth
}

//Holds information about the health of an Elasticsearch index, based on the index level of the cluster health API: https://www.elastic.co/guide/en/elasticsearch/reference/5.6/cluster-health.html
type IndexHealth struct {
Name string
Status string `json:"status"`
ActiveShards int `json:"active_shards"`
RelocatingShards int `json:"relocating_shards"`
InitializingShards int `json:"initializing_shards"`
UnassignedShards int `json:"unassigned_shards"`
}

//Holds slices for persistent and transient cluster settings.
Expand Down Expand Up @@ -314,18 +328,25 @@ func (c *Client) GetIndices() ([]Index, error) {
//Get the health of the cluster.
//
//Use case: You want to see information needed to determine if the Elasticsearch cluster is healthy (green) or not (yellow/red).
func (c *Client) GetHealth() ([]ClusterHealth, error) {
var health []ClusterHealth
err := handleErrWithStruct(c.buildGetRequest("_cat/health?h=cluster,status,relo,init,unassign,pending_tasks,active_shards_percent"), &health)

func (c *Client) GetHealth() (ClusterHealth, error) {
var health ClusterHealth
err := handleErrWithStruct(c.buildGetRequest("_cluster/health?level=indices"), &health)
if err != nil {
return nil, err
return ClusterHealth{}, err
}

for i := range health {
health[i].Message = captionHealth(health[i].Status)
for indexName, index := range health.RawIndices {
index.Name = indexName

if index.Status == "green" {
health.HealthyIndices = append(health.HealthyIndices, index)
} else {
health.UnhealthyIndices = append(health.UnhealthyIndices, index)
}
}

health.Message = captionHealth(health)

return health, nil
}

Expand Down
17 changes: 11 additions & 6 deletions es_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ func TestGetIndices(t *testing.T) {
func TestGetHealth(t *testing.T) {
testSetup := &ServerSetup{
Method: "GET",
Path: "/_cat/health",
Response: `[{"cluster":"elasticsearch_nickcanz","status":"yellow","relo":"0","init":"0","unassign":"5","pending_tasks":"0","active_shards_percent":"50.0%"}]`,
Path: "/_cluster/health",
Response: `{"cluster_name":"mycluster","status":"green","timed_out":false,"number_of_nodes":1,"number_of_data_nodes":1,"active_primary_shards":5,"active_shards":5,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":0,"delayed_unassigned_shards":0,"number_of_pending_tasks":0,"number_of_in_flight_fetch":0,"task_max_waiting_in_queue_millis":0,"active_shards_percent_as_number":100.0,"indices":{"unhealthyIndex":{"status":"yellow"},"healthyIndex":{"status":"green","number_of_shards":5,"number_of_replicas":0,"active_primary_shards":5,"active_shards":5,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":0}}}`,
}

host, port, ts := setupTestServers(t, []*ServerSetup{testSetup})
Expand All @@ -296,13 +296,18 @@ func TestGetHealth(t *testing.T) {
t.Errorf("Unexpected error expected nil, got %s", err)
}

if len(health) != 1 {
t.Errorf("Unexpected health, got %+v", health)
if health.ActiveShards != 5 {
t.Errorf("Unexpected active shards, expected 5, got %d", health.ActiveShards)
}

if health[0].UnassignedShards != 5 {
t.Errorf("Unexpected unassigned shards, expected 5, got %d", health[0].UnassignedShards)
if len(health.HealthyIndices) != 1 || health.HealthyIndices[0].Name != "healthyIndex" {
t.Errorf("Unexpected values in healthy indices, got %+v", health)
}

if len(health.UnhealthyIndices) != 1 || health.UnhealthyIndices[0].Name != "unhealthyIndex" {
t.Errorf("Unexpected values in unhealthy indices, got %+v", health)
}

}

func TestGetSettings(t *testing.T) {
Expand Down
17 changes: 12 additions & 5 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package vulcanizer

import (
"errors"
"fmt"
"strings"

"github.com/tidwall/gjson"
Expand Down Expand Up @@ -32,20 +33,26 @@ func excludeSettingsFromJson(settings []gjson.Result) ExcludeSettings {
}

// Returns caption based on cluster health explaining the meaning of this state.
func captionHealth(health string) (caption string) {
func captionHealth(clusterHealth ClusterHealth) (caption string) {

switch health {
var unhealthyIndexList []string
for _, index := range clusterHealth.UnhealthyIndices {
status := fmt.Sprintf("%s is %s. %d shards are unassigned.", index.Name, index.Status, index.UnassignedShards)
unhealthyIndexList = append(unhealthyIndexList, status)
}

switch clusterHealth.Status {
case "red":
caption := "The cluster is red: One or more primary shards is not allocated on an index or indices. Please check for missing instances and return them to service if possible."
caption := fmt.Sprintf("The cluster is red: One or more primary shards is not allocated on an index or indices. Please check for missing instances and return them to service if possible.\n%s", strings.Join(unhealthyIndexList, "\n"))
return caption
case "yellow":
caption := "The cluster is yellow: One or more replica shards is not allocated on an index or indices. Please check for missing instances and return them to service if possible."
caption := fmt.Sprintf("The cluster is yellow: One or more replica shards is not allocated on an index or indices. Please check for missing instances and return them to service if possible.\n%s", strings.Join(unhealthyIndexList, "\n"))
return caption
case "green":
caption := "The cluster is green: All primary and replica shards are allocated. This does NOT mean the cluster is otherwise healthy."
return caption
default:
return health
return clusterHealth.Status
}
}

Expand Down

0 comments on commit 2f638f3

Please sign in to comment.