Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

Commit 28dba60

Browse files
committed
don't fail during a scrape
Either report all metrics, or none at all.
1 parent 79f8945 commit 28dba60

File tree

7 files changed

+71
-48
lines changed

7 files changed

+71
-48
lines changed

latency.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,34 +57,41 @@ func (lc latencyCollector) describe(ch chan<- *prometheus.Desc) {
5757
}
5858
}
5959

60-
func (lc latencyCollector) collect(conn *as.Connection, ch chan<- prometheus.Metric) error {
60+
func (lc latencyCollector) collect(conn *as.Connection) ([]prometheus.Metric, error) {
6161
stats, err := as.RequestInfo(conn, "latency:")
6262
if err != nil {
63-
return err
63+
return nil, err
6464
}
6565
lat, err := parseLatency(stats["latency:"])
6666
if err != nil {
67-
return err
67+
return nil, err
6868
}
69-
for key, metrics := range lat {
69+
var metrics []prometheus.Metric
70+
for key, ms := range lat {
7071
if key == "batch-index" {
7172
continue // TODO: would be nice to do something with this key
7273
}
7374
ns, op, err := readNS(key)
7475
if err != nil {
75-
return fmt.Errorf("weird latency key %q: %s", key, err)
76+
return nil, fmt.Errorf("weird latency key %q: %s", key, err)
7677
}
77-
for threshold, data := range metrics {
78+
for threshold, data := range ms {
7879
if threshold == "ops/sec" {
7980
m := lc.ops[op]
80-
ch <- prometheus.MustNewConstMetric(m.desc, m.typ, data, ns)
81+
metrics = append(
82+
metrics,
83+
prometheus.MustNewConstMetric(m.desc, m.typ, data, ns),
84+
)
8185
continue
8286
}
8387
m := lc.latency[op]
84-
ch <- prometheus.MustNewConstMetric(m.desc, m.typ, data, ns, threshold)
88+
metrics = append(
89+
metrics,
90+
prometheus.MustNewConstMetric(m.desc, m.typ, data, ns, threshold),
91+
)
8592
}
8693
}
87-
return nil
94+
return metrics, nil
8895
}
8996

9097
// parseLatency returns map with: "[{namespace}]-[op]" -> map[threshold]measurement

main.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func main() {
8383
}
8484

8585
type collector interface {
86-
collect(*as.Connection, chan<- prometheus.Metric) error
86+
collect(*as.Connection) ([]prometheus.Metric, error)
8787
describe(ch chan<- *prometheus.Desc)
8888
}
8989

@@ -131,34 +131,44 @@ func (asc *asCollector) Collect(ch chan<- prometheus.Metric) {
131131
asc.totalScrapes.Inc()
132132
ch <- asc.totalScrapes
133133

134-
conn, err := as.NewConnection(asc.nodeAddr, 3*time.Second)
134+
ms, err := asc.collect()
135135
if err != nil {
136+
log.Print(err)
136137
ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, 0.0)
137138
return
138139
}
140+
ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, 1.0)
141+
for _, m := range ms {
142+
ch <- m
143+
}
144+
}
145+
146+
func (asc *asCollector) collect() ([]prometheus.Metric, error) {
147+
conn, err := as.NewConnection(asc.nodeAddr, 3*time.Second)
148+
if err != nil {
149+
return nil, err
150+
}
151+
defer conn.Close()
152+
139153
if asc.username != "" {
140154
hp, err := hashPassword(asc.password)
141155
if err != nil {
142-
log.Printf("hashPassword: %s", err)
143-
ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, 0.0)
144-
return
156+
return nil, fmt.Errorf("hashPassword: %s", err)
145157
}
146158
if err := conn.Authenticate(asc.username, hp); err != nil {
147-
log.Printf("auth error: %s", err)
148-
ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, 0.0)
149-
return
159+
return nil, fmt.Errorf("auth error: %s", err)
150160
}
151161
}
152-
ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, 1.0)
153-
154-
defer conn.Close()
155162

163+
var metrics []prometheus.Metric
156164
for _, c := range asc.collectors {
157-
if err := c.collect(conn, ch); err != nil {
158-
log.Print(err)
159-
return
165+
ms, err := c.collect(conn)
166+
if err != nil {
167+
return nil, err
160168
}
169+
metrics = append(metrics, ms...)
161170
}
171+
return metrics, nil
162172
}
163173

164174
// take from github.com/aerospike/aerospike-client-go/admin_command.go

metric.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ func parseFloatOrBool(v string) (float64, error) {
3939

4040
// infoCollect parses RequestInfo() results and handles the metrics
4141
func infoCollect(
42-
ch chan<- prometheus.Metric,
4342
metrics cmetrics,
4443
info string,
4544
labelValues ...string,
46-
) {
45+
) []prometheus.Metric {
46+
var res []prometheus.Metric
4747
stats := parseInfo(info)
4848
for key, m := range metrics {
4949
v, ok := stats[key]
@@ -56,8 +56,12 @@ func infoCollect(
5656
log.Printf("%q invalid value %q: %s", key, v, err)
5757
continue
5858
}
59-
ch <- prometheus.MustNewConstMetric(m.desc, m.typ, f, labelValues...)
59+
res = append(
60+
res,
61+
prometheus.MustNewConstMetric(m.desc, m.typ, f, labelValues...),
62+
)
6063
}
64+
return res
6165
}
6266

6367
func parseInfo(s string) map[string]string {

metric_test.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package main
33
import (
44
"reflect"
55
"testing"
6-
"time"
76

87
"github.com/prometheus/client_golang/prometheus"
98
dto "github.com/prometheus/client_model/go"
@@ -105,17 +104,13 @@ func TestInfoCollect(t *testing.T) {
105104
want: `gauge:<value:1 > `,
106105
},
107106
} {
108-
ch := make(chan prometheus.Metric)
109107
metrics := cmetrics{c.field: c.metric}
110-
go infoCollect(ch, metrics, c.payload)
108+
ms := infoCollect(metrics, c.payload)
111109

112-
var metric prometheus.Metric
113-
select {
114-
case metric = <-ch:
115-
case <-time.After(time.Second):
116-
t.Fatalf("timeout for case %d (%q)", n, c.want)
110+
if have, want := len(ms), 1; have != want {
111+
t.Fatalf("have %d, want %d", have, want)
117112
}
118-
113+
metric := ms[0]
119114
m := &dto.Metric{}
120115
metric.Write(m)
121116
if have, want := m.String(), c.want; have != want {

namespaces.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,21 @@ func (nc nsCollector) describe(ch chan<- *prometheus.Desc) {
222222
}
223223
}
224224

225-
func (nc nsCollector) collect(conn *as.Connection, ch chan<- prometheus.Metric) error {
225+
func (nc nsCollector) collect(conn *as.Connection) ([]prometheus.Metric, error) {
226226
info, err := as.RequestInfo(conn, "namespaces")
227227
if err != nil {
228-
return err
228+
return nil, err
229229
}
230+
var metrics []prometheus.Metric
230231
for _, ns := range strings.Split(info["namespaces"], ";") {
231232
nsinfo, err := as.RequestInfo(conn, "namespace/"+ns)
232233
if err != nil {
233-
return err
234+
return nil, err
234235
}
235-
infoCollect(ch, cmetrics(nc), nsinfo["namespace/"+ns], ns)
236+
metrics = append(
237+
metrics,
238+
infoCollect(cmetrics(nc), nsinfo["namespace/"+ns], ns)...,
239+
)
236240
}
237-
return nil
241+
return metrics, nil
238242
}

sets.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,21 @@ func (setc setCollector) describe(ch chan<- *prometheus.Desc) {
4242
}
4343
}
4444

45-
func (setc setCollector) collect(conn *as.Connection, ch chan<- prometheus.Metric) error {
45+
func (setc setCollector) collect(conn *as.Connection) ([]prometheus.Metric, error) {
46+
var metrics []prometheus.Metric
4647
info, err := as.RequestInfo(conn, "sets")
4748
if err != nil {
48-
return err
49+
return nil, err
4950
}
5051
for _, setInfo := range strings.Split(info["sets"], ";") {
5152
if setInfo == "" {
5253
continue
5354
}
5455
setStats := parseInfo(setInfo)
55-
infoCollect(ch, cmetrics(setc), setInfo, setStats["ns"], setStats["set"])
56+
metrics = append(
57+
metrics,
58+
infoCollect(cmetrics(setc), setInfo, setStats["ns"], setStats["set"])...,
59+
)
5660
}
57-
return nil
61+
return metrics, nil
5862
}

stats.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,10 @@ func (sc statsCollector) describe(ch chan<- *prometheus.Desc) {
137137
}
138138
}
139139

140-
func (sc statsCollector) collect(conn *as.Connection, ch chan<- prometheus.Metric) error {
140+
func (sc statsCollector) collect(conn *as.Connection) ([]prometheus.Metric, error) {
141141
res, err := as.RequestInfo(conn, "statistics")
142142
if err != nil {
143-
return err
143+
return nil, err
144144
}
145-
infoCollect(ch, cmetrics(sc), res["statistics"])
146-
return nil
145+
return infoCollect(cmetrics(sc), res["statistics"]), nil
147146
}

0 commit comments

Comments
 (0)