Skip to content

Commit b364a70

Browse files
committed
Adds PR prometheus-community#306 from origin repo
1 parent c4c7d2b commit b364a70

File tree

8 files changed

+646
-1
lines changed

8 files changed

+646
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ elasticsearch_exporter
33
*.tar.gz
44
*-stamp
55
.tarballs
6+
.idea
7+
elasticsearch_exporter.iml

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,9 @@ Pull Requests for any proposed changes.
244244
245245
Please note that we will not merge any changes that encourage insecure
246246
behaviour. If in doubt please open an Issue first to discuss your proposal.
247+
248+
## Docker Image
249+
250+
```
251+
make DOCKER_IMAGE_NAME=infonova/elasticsearch-exporter DOCKER_IMAGE_TAG=<version> docker
252+
```

collector/ilm.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package collector
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
"path"
9+
10+
"github.com/go-kit/kit/log"
11+
"github.com/go-kit/kit/log/level"
12+
"github.com/prometheus/client_golang/prometheus"
13+
)
14+
15+
type ilmMetric struct {
16+
Type prometheus.ValueType
17+
Desc *prometheus.Desc
18+
Value func(val int) float64
19+
Labels func(ilmIndex string, ilmPhase string, ilmAction string, ilmStep string) []string
20+
}
21+
22+
type Ilm struct {
23+
logger log.Logger
24+
client *http.Client
25+
url *url.URL
26+
27+
up prometheus.Gauge
28+
totalScrapes prometheus.Counter
29+
jsonParseFailures prometheus.Counter
30+
31+
ilmMetric ilmMetric
32+
}
33+
34+
func NewIlm(logger log.Logger, client *http.Client, url *url.URL) *Ilm {
35+
return &Ilm{
36+
logger: logger,
37+
client: client,
38+
url: url,
39+
40+
up: prometheus.NewGauge(prometheus.GaugeOpts{
41+
Name: prometheus.BuildFQName(namespace, "ilm", "up"),
42+
Help: "Was the last scrape of the ElasticSearch ILM endpoint successful.",
43+
}),
44+
totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{
45+
Name: prometheus.BuildFQName(namespace, "ilm", "total_scrapes"),
46+
Help: "Current total ElasticSearch ILM scrapes.",
47+
}),
48+
jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{
49+
Name: prometheus.BuildFQName(namespace, "ilm", "json_parse_failures"),
50+
Help: "Number of errors while parsing JSON.",
51+
}),
52+
ilmMetric: ilmMetric{
53+
Type: prometheus.GaugeValue,
54+
Desc: prometheus.NewDesc(
55+
prometheus.BuildFQName(namespace, "ilm", "index_status"),
56+
"Status of ILM policy for index",
57+
[]string{"index", "phase", "action", "step"}, nil),
58+
Value: func(val int) float64 {
59+
return float64(val)
60+
},
61+
Labels: func(ilmIndex string, ilmPhase string, ilmAction string, ilmStep string) []string {
62+
return []string{ilmIndex, ilmPhase, ilmAction, ilmStep}
63+
},
64+
},
65+
}
66+
}
67+
68+
func (i *Ilm) Describe(ch chan<- *prometheus.Desc) {
69+
ch <- i.ilmMetric.Desc
70+
ch <- i.up.Desc()
71+
ch <- i.totalScrapes.Desc()
72+
ch <- i.jsonParseFailures.Desc()
73+
}
74+
75+
func (i *Ilm) Bool2int(managed bool) int {
76+
if managed {
77+
return 1
78+
} else {
79+
return 0
80+
}
81+
}
82+
83+
func (i *Ilm) fetchAndDecodeIlm() (IlmResponse, error) {
84+
var ir IlmResponse
85+
86+
u := *i.url
87+
u.Path = path.Join(u.Path, "/_all/_ilm/explain")
88+
89+
res, err := i.client.Get(u.String())
90+
if err != nil {
91+
return ir, fmt.Errorf("failed to get index stats from %s://%s:%s%s: %s",
92+
u.Scheme, u.Hostname(), u.Port(), u.Path, err)
93+
}
94+
95+
defer func() {
96+
err = res.Body.Close()
97+
if err != nil {
98+
_ = level.Warn(i.logger).Log(
99+
"msg", "failed to close http.Client",
100+
"err", err,
101+
)
102+
}
103+
}()
104+
105+
if res.StatusCode != http.StatusOK {
106+
return ir, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode)
107+
}
108+
109+
if err := json.NewDecoder(res.Body).Decode(&ir); err != nil {
110+
i.jsonParseFailures.Inc()
111+
return ir, err
112+
}
113+
114+
return ir, nil
115+
}
116+
117+
func (i *Ilm) Collect(ch chan<- prometheus.Metric) {
118+
defer func() {
119+
ch <- i.up
120+
ch <- i.totalScrapes
121+
ch <- i.jsonParseFailures
122+
}()
123+
124+
// indices
125+
ilmResp, err := i.fetchAndDecodeIlm()
126+
if err != nil {
127+
i.up.Set(0)
128+
_ = level.Warn(i.logger).Log(
129+
"msg", "failed to fetch and decode ILM stats",
130+
"err", err,
131+
)
132+
return
133+
}
134+
i.totalScrapes.Inc()
135+
i.up.Set(1)
136+
137+
for indexName, indexIlm := range ilmResp.Indices {
138+
ch <- prometheus.MustNewConstMetric(
139+
i.ilmMetric.Desc,
140+
i.ilmMetric.Type,
141+
i.ilmMetric.Value(i.Bool2int(indexIlm.Managed)),
142+
i.ilmMetric.Labels(indexName, indexIlm.Phase, indexIlm.Action, indexIlm.Step)...,
143+
)
144+
}
145+
}

collector/ilm_response.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package collector
2+
3+
type IlmResponse struct {
4+
Indices map[string]IlmIndexResponse `json:"indices"`
5+
}
6+
7+
type IlmIndexResponse struct {
8+
Index string `json:"index"`
9+
Managed bool `json:"managed"`
10+
Phase string `json:"phase"`
11+
Action string `json:"action"`
12+
Step string `json:"step"`
13+
}

collector/ilm_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package collector
2+
3+
import (
4+
"fmt"
5+
"github.com/go-kit/kit/log"
6+
"net/http"
7+
"net/http/httptest"
8+
"net/url"
9+
"testing"
10+
)
11+
12+
func TestIlm(t *testing.T) {
13+
ti := map[string]string{
14+
"7.3.2": `{"indices":{"foo_11":{"index":"foo_1","managed":true,"policy":"foo_policy","lifecycle_date_millis":1575630854324,"phase":"hot","phase_time_millis":1575605054674,"action":"complete","action_time_millis":1575630855862,"step":"complete","step_time_millis":1575630855862,"phase_execution":{"policy":"foo_policy","phase_definition":{"min_age":"0ms","actions":{"rollover":{"max_size":"15gb","max_age":"1d"},"set_priority":{"priority":100}}},"version":7,"modified_date_in_millis":1573070716617}}}}`,
15+
}
16+
for ver, out := range ti {
17+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
18+
fmt.Fprintln(w, out)
19+
}))
20+
defer ts.Close()
21+
22+
u, err := url.Parse(ts.URL)
23+
if err != nil {
24+
t.Fatalf("Failed to parse URL: %s", err)
25+
}
26+
i := NewIlm(log.NewNopLogger(), http.DefaultClient, u)
27+
ilm, err := i.fetchAndDecodeIlm()
28+
if err != nil {
29+
t.Fatalf("Failed to fetch or decode ILM stats: %s", err)
30+
}
31+
t.Logf("[%s] ILM Response: %+v", ver, ilm)
32+
for ilmIndex, stats := range ilm.Indices {
33+
t.Logf(
34+
"Index: %s - Managed: %t - Action: %s - Phase: %s - Step: %s",
35+
ilmIndex,
36+
stats.Managed,
37+
stats.Action,
38+
stats.Phase,
39+
stats.Step,
40+
)
41+
if stats.Managed != true {
42+
t.Errorf("Wrong parsed value of managed flag")
43+
}
44+
}
45+
46+
}
47+
}

go.mod

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module github.com/justwatchcom/elasticsearch_exporter
2+
3+
go 1.13
4+
5+
require (
6+
github.com/alecthomas/gometalinter v3.0.0+incompatible // indirect
7+
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
8+
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
9+
github.com/beorn7/perks v1.0.1
10+
github.com/blang/semver v3.5.2-0.20180723201105-3c1074078d32+incompatible
11+
github.com/go-kit/kit v0.9.0
12+
github.com/go-logfmt/logfmt v0.4.0
13+
github.com/go-stack/stack v1.8.0
14+
github.com/golang/protobuf v1.3.5
15+
github.com/golangci/golangci-lint v1.24.0 // indirect
16+
github.com/google/go-github/v25 v25.1.3 // indirect
17+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
18+
github.com/imdario/mergo v0.3.7-0.20181107191138-ca3dcc1022ba
19+
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515
20+
github.com/matttproud/golang_protobuf_extensions v1.0.1
21+
github.com/nicksnyder/go-i18n v2.0.3+incompatible // indirect
22+
github.com/pkg/errors v0.9.1 // indirect
23+
github.com/prometheus/client_golang v1.5.1
24+
github.com/prometheus/client_model v0.2.0
25+
github.com/prometheus/common v0.9.1
26+
github.com/prometheus/procfs v0.0.11
27+
github.com/prometheus/promu v0.5.0 // indirect
28+
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
29+
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
30+
golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4 // indirect
31+
google.golang.org/appengine v1.6.5 // indirect
32+
gopkg.in/alecthomas/kingpin.v2 v2.2.6
33+
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780 // indirect
34+
gopkg.in/yaml.v2 v2.2.8 // indirect
35+
)

0 commit comments

Comments
 (0)