Skip to content

Commit edd28cd

Browse files
authored
Add a common collector interface (#521)
This provides the groundwork to refactor the collectors into a more consistent interface. It borrows some influence from the node_exporter with the goal to easily filter in/out collector modules. The execute func also provides a context for potential cancellation. Signed-off-by: Joe Adams <github@joeadams.io>
1 parent 6b6eeae commit edd28cd

File tree

2 files changed

+100
-4
lines changed

2 files changed

+100
-4
lines changed

collector/cluster_health.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ import (
2626
"github.com/prometheus/client_golang/prometheus"
2727
)
2828

29-
const (
30-
namespace = "elasticsearch"
31-
)
32-
3329
var (
3430
colors = []string{"green", "yellow", "red"}
3531
defaultClusterHealthLabels = []string{"cluster"}

collector/collector.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2022 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// Package collector includes all individual collectors to gather and export elasticsearch metrics.
15+
package collector
16+
17+
import (
18+
"context"
19+
"net/http"
20+
"net/url"
21+
"sync"
22+
"time"
23+
24+
"github.com/go-kit/log"
25+
"github.com/go-kit/log/level"
26+
"github.com/prometheus/client_golang/prometheus"
27+
)
28+
29+
// Namespace defines the common namespace to be used by all metrics.
30+
const namespace = "elasticsearch"
31+
32+
var (
33+
scrapeDurationDesc = prometheus.NewDesc(
34+
prometheus.BuildFQName(namespace, "scrape", "duration_seconds"),
35+
"elasticsearch_exporter: Duration of a collector scrape.",
36+
[]string{"collector"},
37+
nil,
38+
)
39+
scrapeSuccessDesc = prometheus.NewDesc(
40+
prometheus.BuildFQName(namespace, "scrape", "success"),
41+
"elasticsearch_exporter: Whether a collector succeeded.",
42+
[]string{"collector"},
43+
nil,
44+
)
45+
)
46+
47+
// Collector is the interface a collector has to implement.
48+
type Collector interface {
49+
// Get new metrics and expose them via prometheus registry.
50+
Update(context.Context, chan<- prometheus.Metric) error
51+
}
52+
53+
type ElasticsearchCollector struct {
54+
Collectors map[string]Collector
55+
logger log.Logger
56+
}
57+
58+
// NewElasticsearchCollector creates a new ElasticsearchCollector
59+
func NewElasticsearchCollector(logger log.Logger, httpClient *http.Client, esURL *url.URL) (*ElasticsearchCollector, error) {
60+
collectors := make(map[string]Collector)
61+
62+
return &ElasticsearchCollector{Collectors: collectors, logger: logger}, nil
63+
}
64+
65+
// Describe implements the prometheus.Collector interface.
66+
func (e ElasticsearchCollector) Describe(ch chan<- *prometheus.Desc) {
67+
ch <- scrapeDurationDesc
68+
ch <- scrapeSuccessDesc
69+
}
70+
71+
// Collect implements the prometheus.Collector interface.
72+
func (e ElasticsearchCollector) Collect(ch chan<- prometheus.Metric) {
73+
wg := sync.WaitGroup{}
74+
ctx := context.TODO()
75+
wg.Add(len(e.Collectors))
76+
for name, c := range e.Collectors {
77+
go func(name string, c Collector) {
78+
execute(ctx, name, c, ch, e.logger)
79+
wg.Done()
80+
}(name, c)
81+
}
82+
wg.Wait()
83+
}
84+
85+
func execute(ctx context.Context, name string, c Collector, ch chan<- prometheus.Metric, logger log.Logger) {
86+
begin := time.Now()
87+
err := c.Update(ctx, ch)
88+
duration := time.Since(begin)
89+
var success float64
90+
91+
if err != nil {
92+
_ = level.Error(logger).Log("msg", "collector failed", "name", name, "duration_seconds", duration.Seconds(), "err", err)
93+
success = 0
94+
} else {
95+
_ = level.Debug(logger).Log("msg", "collector succeeded", "name", name, "duration_seconds", duration.Seconds())
96+
success = 1
97+
}
98+
ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), name)
99+
ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, success, name)
100+
}

0 commit comments

Comments
 (0)