How To Get An Elasticsearch Cluster's Health And Stats In Golang

Introduction

This tutorial will cover how to use the Olivere driver to obtain an Elasticsearch cluster health stats with Golang. A widely utilized third-party driver, the Olivere driver supports multiple versions of Elasticsearch. The default port for Elasticsearch is 9200, however, this can be configured in the cluster’s elasticsearch.yml file if and as needed.

Prerequisites

  • An Elasticsearch cluster needs to be running on the server.

  • The Golang program must be installed on the same machine running the Elasticsearch cluster. Make sure to export the $GOROOT and $GOPATH paths after installation. Type go version into a terminal window to confirm installation and obtain the installed Golang version.

  • The Olivere Go driver for Elasticsearch must be installed on the same machine running Golang and the Elasticsearch cluster.

  • Have sudo access to the Linux server or macOS system.

Note: A private key with sudo access is required to remotely access the server through SSH.

How to Install the Olivere Golang Package Driver for Elasticsearch

The following command will install the package for Elasticsearch 7.x:

go get gopkg.in/olivere/elastic.v7

For older versions of the package driver, change the 7 at the end of the get command to match the major version number of the current Elasticsearch cluster. If needed, the following cURL request will obtain the cluster’s version number:

curl -XGET localhost:9200

Terminal screenshot using cURL to get Elasticsearch version and go get to install the Olivere driver for Golang

How to Create a Project Directory and Go Script in the Server’s GOPATH

NOTE: This step can be omitted if an Elasticsearch Golang project is already set up.

Navigate to your server’s $GOPATH (cd $GOPATH) and create a sub-directory somewhere in that path for the Elasticsearch application. Execute a cd into that project directory and create a Go script with the .go file extension as shown here:

Terminal screenshot getting go version and $GOPATH to make an Elasticsearch project directory

How to Declare a Main() and Import the Elastic Driver’s Packages

Execute the following commands to declare a package the main() at the top of the script and import the necessary packages that will enable Golang to connect to Elasticsearch and make API calls:

package main

import (
"context" // Context object for Do() methods
"fmt" // Format and print cluster data
"log" // Log errors and quit
"reflect" // Get object methods and attributes
"time" // Set a timeout for the connection

// Import the Olivere Golang driver for Elasticsearch
"github.com/olivere/elastic"
)

How to Connect to Elasticsearch with the Olivere Driver

Execute the following script to declare the main() function and create a new client instance of the elastic library:

func main() {

// Instantiate a client instance of the elastic library
client, err := elastic.NewClient(
elastic.SetSniff(true),
elastic.SetURL("http://localhost:9200"),
elastic.SetHealthcheckInterval(5*time.Second), // quit trying after 5 seconds
)

// Declare Context object for API calls
ctx := context.Background()

// Print client information
fmt.Println("client:", client)
fmt.Println("client TYPE:", reflect.TypeOf(client))

How to log any connection errors returned from the Elasticsearch cluster

Execute the following commands to log any connection errors:

// Check and see if olivere's NewClient() method returned an error
if err != nil {
fmt.Println("elastic.NewClient() ERROR: %v", err)
log.Fatalf("quiting connection..")
}

Having Elasticsearch Return Cluster Stats Information with Golang

The Client library has a ClusterStats() library that can return vital information on the Elasticsearch cluster running on the server.

How to instantiate a ClusterStatsService object

Execute the following command:

// Get elastic.ClusterStatsService
stats := client.ClusterStats()

How to get a Golang map[] response of the Elasticsearch cluster stats

Pass the ctx context object instantiated earlier to the ClusterStatsService object’s Do() method and have it return a ClusterStatsResponse using the following script:

// Use the Do() method to return a *elastic.ClusterStatsResponse map[]
statsDo, statErr := stats.Do(ctx)
fmt.Println("nstats.Do(ctx) TYPE:", reflect.TypeOf(stat))

How to print attributes of the ClusterStatsResponse

Execute the following command:

// Check for cluster stat's errors
if statErr != nil {
fmt.Println("nstatErr: %v", statErr)
} else {
// Print some attributes of the ClusterStatsResponse
fmt.Println("nClusterStats().Do():", statsDo)
fmt.Println("ClusterStats().Do() TYPE:", reflect.TypeOf(statsDo))
fmt.Println("ClusterName:", statsDo.ClusterName)
fmt.Println("ClusterStatus:", statsDo.Status)
fmt.Println("ClusterUUID:", statsDo.ClusterUUID)
}

The following script are the complete struct framework fields for the stats response:

 

// ClusterStatsResponse is the response of ClusterStatsService.Do. type ClusterStatsResponse struct { Timestamp int64 json:"timestamp" ClusterName string json:"cluster_name" ClusterUUID string json:"cluster_uuid" Status string json:"status,omitempty" // e.g. green Indices ClusterStatsIndices json:"indices" Nodes ClusterStatsNodes json:"nodes" } `

How to Return the Elasticsearch Cluster Health Stats Golang with the Olivere Driver

How to use the ClusterHealth library to get an Elasticsearch cluster’s health

Execute the following code to create an instance of the client’s ClusterHealth() method library:

// Print the cluster health for the client
health := client.ClusterHealth()

How to use the driver’s ClusterHealthService to get a response from Elasticsearch

Call the *elastic.ClusterHealthService object’s Do() method to have it make an API call to Elasticsearch. This will return a mapped struct response containing information about the cluster’s health. Execute this function with the following commands:

// Use the Do() method to return a ClusterHealthResponse
resp, err := health.Do(ctx)
if err != nil {
fmt.Println("ClusterHealth.Do() ERROR: %v", err)
} else {
...

How to print attributes of the ClusterHealthResponse object

If no errors are found, execute the following script to obtaining the cluster’s health information by accessing attributes of the response object:

fmt.Println("nclient.ClusterHealth:", reflect.TypeOf(health))
fmt.Println("client.ClusterHealth.Do():", reflect.TypeOf(resp))

fmt.Println("resp TYPE:", reflect.TypeOf(resp))
fmt.Println("resp:", resp)
fmt.Println("ClusterName:", resp.ClusterName)
fmt.Println("Status:", resp.Status)
}

Here are all of the attributes for the ClusterHealthResponse struct framework:

type ClusterHealthResponse struct {
ClusterName string `json:"cluster_name"`
Status string `json:"status"`
TimedOut bool `json:"timed_out"`
NumberOfNodes int `json:"number_of_nodes"`
NumberOfDataNodes int `json:"number_of_data_nodes"`
ActivePrimaryShards int `json:"active_primary_shards"`
ActiveShards int `json:"active_shards"`
RelocatingShards int `json:"relocating_shards"`
InitializedShards int `json:"initialized_shards"`
UnassignedShards int `json:"unassigned_shards"`
}

Conclusion

This tutorial covered how to use the Olivere Golang driver to make API calls to the server’s Elasticsearch cluster to obtain cluster stats and health information, shown in the following image:

Terminal screenshot of the Elasticsearch cluster health and stats output in Golang

Specifically, the tutorial explained how to install the Olivere Golang package driver, create a project directory and Go script, import the Elastic driver’s packages, connect to Elasticsearch with the Olivere driver, how to have Elasticsearch return cluster stats information and how to print attributes. Remember that the Elasticsearch cluster, the Golang program and the Olivere driver must all be installed on the same machine.

Just the Code

package main

import (
"context" // Context object for Do() methods
"fmt" // Format and print cluster data
"log" // Log errors and quit
"reflect" // Get object methods and attributes
"time" // Set a timeout for the connection

// Import the Olivere Golang driver for Elasticsearch
"github.com/olivere/elastic"
)

func main() {

// Instantiate a client instance of the elastic library
client, err := elastic.NewClient(
elastic.SetSniff(true),
elastic.SetURL("http://localhost:9200"),
elastic.SetHealthcheckInterval(5*time.Second), // quit trying after 5 seconds
)

//
Declare Context object for API calls
ctx := context.Background()

// Print client information
fmt.Println("client:", client)
fmt.Println("client TYPE:", reflect.TypeOf(client))

// Check and see if olivere's NewClient() method returned an error
if err != nil {
fmt.Println("elastic.NewClient() ERROR: %v", err)
log.Fatalf("quiting connection..")
}

/*
Get the cluster stats using the driver's ClusterStatsService
*/

// Get elastic.ClusterStatsService
stats := client.ClusterStats()

// Use the Do() method to return a *elastic.ClusterStatsResponse map[]
statsDo, statErr := stats.Do(ctx)
fmt.Println("nstats.Do(ctx) TYPE:", reflect.TypeOf(statsDo))

// Get the attributes for the cluster stats object
t := reflect.TypeOf(stats)
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
fmt.Println("nelastic.ClusterStatsService NAME:", i, method.Name)
fmt.Println("method:", i, method)
}
print("nn")

/*
Get health stats using the driver's ClusterHealthService
*/

// Print the cluster health for the client
health := client.ClusterHealth()

// Get the attributes of the ClusterHealth() method
t = reflect.TypeOf(health)
fmt.Println("health:", reflect.TypeOf(health))
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
fmt.Println("nclient.ClusterHealth NAME:", i, method.Name)
fmt.Println("method:", method)
}

// Use the Do() method to return a ClusterHealthResponse
resp, err := health.Do(ctx)
if err != nil {
fmt.Println("ClusterHealth.Do() ERROR: %v", err)
} else {
fmt.Println("nclient.ClusterHealth:", reflect.TypeOf(health))
fmt.Println("client.ClusterHealth.Do():", reflect.TypeOf(resp))

fmt.Println("resp TYPE:", reflect.TypeOf(resp))
fmt.Println("resp:", resp)
fmt.Println("ClusterName:", resp.ClusterName)
fmt.Println("Status:", resp.Status)
}

/*
Get health stats using the driver's NewClusterHealthService
*/

// Declare a elastic.ClusterHealthService object
healthService := elastic.NewClusterHealthService(client)
fmt.Println("nhealthService TYPE:", reflect.TypeOf(healthService))
fmt.Println(healthService.Pretty(true))

// Call Do() to return a elastic.ClusterHealthResponse
serv, err := healthService.Do(ctx)

// Check for health service errors
if err != nil {
fmt.Println("healthService.Do() ERROR: %v", err)
} else {
fmt.Println("healthService TYPE:", reflect.TypeOf(serv))
fmt.Println("healthService.Do():", serv)
fmt.Println("ClusterName:", serv.ClusterName)
fmt.Println("Status:", serv.Status)
}

// Check for cluster stat's errors
if statErr != nil {
fmt.Println("nstatErr: %v", statErr)
} else {
// Print some attributes of the ClusterStatsResponse
fmt.Println("nClusterStats().Do():", statsDo)
fmt.Println("ClusterStats().Do() TYPE:", reflect.TypeOf(statsDo))
fmt.Println("ClusterName:", statsDo.ClusterName)
fmt.Println("ClusterStatus:", statsDo.Status)
fmt.Println("ClusterUUID:", statsDo.ClusterUUID)
}

}

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.