From 4232fd71c410a14036011da74962232c9b865cee Mon Sep 17 00:00:00 2001 From: Steven Cipriano Date: Tue, 17 May 2022 16:48:23 -0700 Subject: [PATCH] move aliases to separate informational metrics Signed-off-by: Steven Cipriano --- README.md | 2 +- collector/indices.go | 97 +++++++++++++++++++++++++-------------- collector/indices_test.go | 4 +- main.go | 6 +-- 4 files changed, 68 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 2ce02695..de19a387 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ elasticsearch_exporter --help | es.indices | 1.0.2 | If true, query stats for all indices in the cluster. | false | | es.indices_settings | 1.0.4rc1 | If true, query settings stats for all indices in the cluster. | false | | es.indices_mappings | 1.2.0 | If true, query stats for mappings of all indices of the cluster. | false | -| es.aliases | 1.0.4rc1 | If true, include aliases in label for all index and shard stats. | false | +| es.no-aliases | 1.0.4rc1 | If true, exclude informational aliases metrics. | false | | es.shards | 1.0.3rc1 | If true, query stats for all indices in the cluster, including shard-level stats (implies `es.indices=true`). | false | | es.snapshots | 1.0.4rc1 | If true, query stats for the cluster snapshots. | false | | es.timeout | 1.0.2 | Timeout for trying to get stats from Elasticsearch. (ex: 20s) | 5s | diff --git a/collector/indices.go b/collector/indices.go index 83872caf..57401b23 100644 --- a/collector/indices.go +++ b/collector/indices.go @@ -16,18 +16,16 @@ package collector import ( "encoding/json" "fmt" + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/prometheus-community/elasticsearch_exporter/pkg/clusterinfo" + "github.com/prometheus/client_golang/prometheus" "io/ioutil" "net/http" "net/url" "path" "sort" "strconv" - "strings" - - "github.com/go-kit/log" - "github.com/go-kit/log/level" - "github.com/prometheus-community/elasticsearch_exporter/pkg/clusterinfo" - "github.com/prometheus/client_golang/prometheus" ) type labels struct { @@ -49,6 +47,13 @@ type shardMetric struct { Labels labels } +type aliasMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func() float64 + Labels labels +} + // Indices information struct type Indices struct { logger log.Logger @@ -65,16 +70,14 @@ type Indices struct { indexMetrics []*indexMetric shardMetrics []*shardMetric + aliasMetrics []*aliasMetric } // NewIndices defines Indices Prometheus metrics -func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards bool, aliases bool) *Indices { +func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards bool, excludeAliases bool) *Indices { indexLabels := labels{ keys: func(...string) []string { - if aliases { - return []string{"index", "aliases", "cluster"} - } return []string{"index", "cluster"} }, values: func(lastClusterinfo *clusterinfo.Response, s ...string) []string { @@ -89,9 +92,6 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo shardLabels := labels{ keys: func(...string) []string { - if aliases { - return []string{"index", "shard", "node", "primary", "aliases", "cluster"} - } return []string{"index", "shard", "node", "primary", "cluster"} }, values: func(lastClusterinfo *clusterinfo.Response, s ...string) []string { @@ -104,12 +104,26 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo }, } + aliasLabels := labels{ + keys: func(...string) []string { + return []string{"index", "alias", "cluster"} + }, + values: func(lastClusterinfo *clusterinfo.Response, s ...string) []string { + if lastClusterinfo != nil { + return append(s, lastClusterinfo.ClusterName) + } + // this shouldn't happen, as the clusterinfo Retriever has a blocking + // Run method. It blocks until the first clusterinfo call has succeeded + return append(s, "unknown_cluster") + }, + } + indices := &Indices{ logger: logger, client: client, url: url, shards: shards, - aliases: aliases, + aliases: !excludeAliases, clusterInfoCh: make(chan *clusterinfo.Response), lastClusterInfo: &clusterinfo.Response{ ClusterName: "unknown_cluster", @@ -1032,6 +1046,21 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo Labels: shardLabels, }, }, + + aliasMetrics: []*aliasMetric{ + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices", "aliases"), + "Record aliases associated with an index", + aliasLabels.keys(), nil, + ), + Value: func() float64 { + return float64(1) + }, + Labels: aliasLabels, + }, + }, } // start go routine to fetch clusterinfo updates and save them to lastClusterinfo @@ -1183,28 +1212,32 @@ func (i *Indices) Collect(ch chan<- prometheus.Metric) { } i.up.Set(1) - // Index stats - for indexName, indexStats := range indexStatsResp.Indices { - var labelValues []string - var aliasesString string - if i.aliases { - if aliasNames, ok := indexStatsResp.Aliases[indexName]; ok { - aliasesString = strings.Join(aliasNames, ",") + // Alias stats + if i.aliases { + for _, metric := range i.aliasMetrics { + for indexName, aliases := range indexStatsResp.Aliases { + for _, alias := range aliases { + labelValues := metric.Labels.values(i.lastClusterInfo, indexName, alias) + + ch <- prometheus.MustNewConstMetric( + metric.Desc, + metric.Type, + metric.Value(), + labelValues..., + ) + } } } + } + // Index stats + for indexName, indexStats := range indexStatsResp.Indices { for _, metric := range i.indexMetrics { - if i.aliases { - labelValues = metric.Labels.values(i.lastClusterInfo, indexName, aliasesString) - } else { - labelValues = metric.Labels.values(i.lastClusterInfo, indexName) - } - ch <- prometheus.MustNewConstMetric( metric.Desc, metric.Type, metric.Value(indexStats), - labelValues..., + metric.Labels.values(i.lastClusterInfo, indexName)..., ) } @@ -1213,17 +1246,11 @@ func (i *Indices) Collect(ch chan<- prometheus.Metric) { // gaugeVec := prometheus.NewGaugeVec(metric.Opts, metric.Labels) for shardNumber, shards := range indexStats.Shards { for _, shard := range shards { - if i.aliases { - labelValues = metric.Labels.values(i.lastClusterInfo, indexName, shardNumber, shard.Routing.Node, strconv.FormatBool(shard.Routing.Primary), aliasesString) - } else { - labelValues = metric.Labels.values(i.lastClusterInfo, indexName, shardNumber, shard.Routing.Node, strconv.FormatBool(shard.Routing.Primary)) - } - ch <- prometheus.MustNewConstMetric( metric.Desc, metric.Type, metric.Value(shard), - labelValues..., + metric.Labels.values(i.lastClusterInfo, indexName, shardNumber, shard.Routing.Node, strconv.FormatBool(shard.Routing.Primary))..., ) } } diff --git a/collector/indices_test.go b/collector/indices_test.go index 1d164b65..98ffb0f9 100644 --- a/collector/indices_test.go +++ b/collector/indices_test.go @@ -49,7 +49,7 @@ func TestIndices(t *testing.T) { if err != nil { t.Fatalf("Failed to parse URL: %s", err) } - i := NewIndices(log.NewNopLogger(), http.DefaultClient, u, false, false) + i := NewIndices(log.NewNopLogger(), http.DefaultClient, u, false, true) stats, err := i.fetchAndDecodeIndexStats() if err != nil { t.Fatalf("Failed to fetch or decode indices stats: %s", err) @@ -123,7 +123,7 @@ func TestAliases(t *testing.T) { if err != nil { t.Fatalf("Failed to parse URL: %s", err) } - i := NewIndices(log.NewNopLogger(), http.DefaultClient, u, false, true) + i := NewIndices(log.NewNopLogger(), http.DefaultClient, u, false, false) stats, err := i.fetchAndDecodeIndexStats() if err != nil { t.Fatalf("Failed to fetch or decode indices stats: %s", err) diff --git a/main.go b/main.go index 310a3282..adaa47ac 100644 --- a/main.go +++ b/main.go @@ -73,8 +73,8 @@ func main() { esExportIndicesMappings = kingpin.Flag("es.indices_mappings", "Export stats for mappings of all indices of the cluster."). Default("false").Bool() - esExportIndexAliases = kingpin.Flag("es.aliases", - "Include alias labels with exported index and shard stats."). + esNoExportIndexAliases = kingpin.Flag("es.no-aliases", + "Exclude informational alias metrics."). Default("false").Bool() esExportClusterSettings = kingpin.Flag("es.cluster_settings", "Export stats for cluster settings."). @@ -167,7 +167,7 @@ func main() { prometheus.MustRegister(collector.NewNodes(logger, httpClient, esURL, *esAllNodes, *esNode)) if *esExportIndices || *esExportShards { - iC := collector.NewIndices(logger, httpClient, esURL, *esExportShards, *esExportIndexAliases) + iC := collector.NewIndices(logger, httpClient, esURL, *esExportShards, *esNoExportIndexAliases) prometheus.MustRegister(iC) if registerErr := clusterInfoRetriever.RegisterConsumer(iC); registerErr != nil { _ = level.Error(logger).Log("msg", "failed to register indices collector in cluster info")