1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
package collector
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"path"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/imdario/mergo"
"github.com/prometheus/client_golang/prometheus"
)
// ClusterSettings information struct
type ClusterSettings struct {
logger log.Logger
client *http.Client
url *url.URL
up prometheus.Gauge
shardAllocationEnabled prometheus.Gauge
totalScrapes, jsonParseFailures prometheus.Counter
}
// NewClusterSettings defines Cluster Settings Prometheus metrics
func NewClusterSettings(logger log.Logger, client *http.Client, url *url.URL) *ClusterSettings {
return &ClusterSettings{
logger: logger,
client: client,
url: url,
up: prometheus.NewGauge(prometheus.GaugeOpts{
Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "up"),
Help: "Was the last scrape of the ElasticSearch cluster settings endpoint successful.",
}),
totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{
Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "total_scrapes"),
Help: "Current total ElasticSearch cluster settings scrapes.",
}),
shardAllocationEnabled: prometheus.NewGauge(prometheus.GaugeOpts{
Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "shard_allocation_enabled"),
Help: "Current mode of cluster wide shard routing allocation settings.",
}),
jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{
Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "json_parse_failures"),
Help: "Number of errors while parsing JSON.",
}),
}
}
// Describe add Snapshots metrics descriptions
func (cs *ClusterSettings) Describe(ch chan<- *prometheus.Desc) {
ch <- cs.up.Desc()
ch <- cs.totalScrapes.Desc()
ch <- cs.shardAllocationEnabled.Desc()
ch <- cs.jsonParseFailures.Desc()
}
func (cs *ClusterSettings) getAndParseURL(u *url.URL, data interface{}) error {
res, err := cs.client.Get(u.String())
if err != nil {
return fmt.Errorf("failed to get from %s://%s:%s%s: %s",
u.Scheme, u.Hostname(), u.Port(), u.Path, err)
}
defer func() {
err = res.Body.Close()
if err != nil {
_ = level.Warn(cs.logger).Log(
"msg", "failed to close http.Client",
"err", err,
)
}
}()
if res.StatusCode != http.StatusOK {
return fmt.Errorf("HTTP Request failed with code %d", res.StatusCode)
}
if err := json.NewDecoder(res.Body).Decode(data); err != nil {
cs.jsonParseFailures.Inc()
return err
}
return nil
}
func (cs *ClusterSettings) fetchAndDecodeClusterSettingsStats() (ClusterSettingsResponse, error) {
u := *cs.url
u.Path = path.Join(u.Path, "/_cluster/settings")
q := u.Query()
q.Set("include_defaults", "true")
u.RawPath = q.Encode()
var csfr ClusterSettingsFullResponse
var csr ClusterSettingsResponse
err := cs.getAndParseURL(&u, &csfr)
if err != nil {
return csr, err
}
err = mergo.Merge(&csr, csfr.Defaults, mergo.WithOverride)
if err != nil {
return csr, err
}
err = mergo.Merge(&csr, csfr.Persistent, mergo.WithOverride)
if err != nil {
return csr, err
}
err = mergo.Merge(&csr, csfr.Transient, mergo.WithOverride)
return csr, err
}
// Collect gets cluster settings metric values
func (cs *ClusterSettings) Collect(ch chan<- prometheus.Metric) {
cs.totalScrapes.Inc()
defer func() {
ch <- cs.up
ch <- cs.totalScrapes
ch <- cs.jsonParseFailures
ch <- cs.shardAllocationEnabled
}()
csr, err := cs.fetchAndDecodeClusterSettingsStats()
if err != nil {
cs.shardAllocationEnabled.Set(0)
cs.up.Set(0)
_ = level.Warn(cs.logger).Log(
"msg", "failed to fetch and decode cluster settings stats",
"err", err,
)
return
}
cs.up.Set(1)
shardAllocationMap := map[string]int{
"all": 0,
"primaries": 1,
"new_primaries": 2,
"none": 3,
}
cs.shardAllocationEnabled.Set(float64(shardAllocationMap[csr.Cluster.Routing.Allocation.Enabled]))
}
|