Skip to content

Commit

Permalink
Add metric 'rabbitmq_up'
Browse files Browse the repository at this point in the history
The new metric exposes whether the last scrape of RabbitMQ was
successful. It is inspired by the haproxy_exporter which exposes the
metric `haproxy_up`.
The value of `rabbitmq_up` is either `1` or `0`. It can be used to
determine whether the RabbitMQ process being scraped is up-and-running.

In order to be able to set the metric, some functions have been
rewritten to return error values instead of using callbacks.
  • Loading branch information
wndhydrnt committed Aug 24, 2016
1 parent 1dce0cc commit b6958bc
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 19 deletions.
14 changes: 12 additions & 2 deletions exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,27 @@ type exporter struct {
queueMetricsGauge map[string]*prometheus.GaugeVec
queueMetricsCounter map[string]*prometheus.CounterVec
overviewMetrics map[string]prometheus.Gauge
upMetric prometheus.Gauge
}

func newExporter() *exporter {
return &exporter{
queueMetricsGauge: queueGaugeVec,
queueMetricsCounter: queueCounterVec,
overviewMetrics: overviewMetricDescription,
upMetric: upMetricDescription,
}
}

func (e *exporter) fetchRabbit() {
rabbitMqOverviewData := getOverviewMap(config)
rabbitMqQueueData := getQueueInfo(config)
rabbitMqOverviewData, overviewError := getOverviewMap(config)
rabbitMqQueueData, queueError := getQueueInfo(config)

if overviewError != nil || queueError != nil {
e.upMetric.Set(0)
} else {
e.upMetric.Set(1)
}

log.WithField("overviewData", rabbitMqOverviewData).Debug("Overview data")
for key, gauge := range e.overviewMetrics {
Expand Down Expand Up @@ -87,6 +95,8 @@ func (e *exporter) Collect(ch chan<- prometheus.Metric) {

e.fetchRabbit()

e.upMetric.Collect(ch)

for _, gauge := range e.overviewMetrics {
gauge.Collect(ch)
}
Expand Down
1 change: 1 addition & 0 deletions exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ func TestWholeApp(t *testing.T) {
expectSubstring(t, body, `rabbitmq_queue_memory{queue="myQueue4",vhost="vhost4"} 13912`)
expectSubstring(t, body, `rabbitmq_queue_messages_published_total{queue="myQueue1",vhost="/"} 6`)
expectSubstring(t, body, `rabbitmq_queue_disk_writes{queue="myQueue1",vhost="/"} 6`)
expectSubstring(t, body, `rabbitmq_up 1`)
}
2 changes: 2 additions & 0 deletions metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const (
var (
queueLabelNames = []string{"vhost", "queue"}

upMetricDescription = newMetric("up", "Was the last scrape of rabbitmq successful.")

overviewMetricDescription = map[string]prometheus.Gauge{
"object_totals.channels": newMetric("channelsTotal", "Total number of open channels."),
"object_totals.connections": newMetric("connectionsTotal", "Total number of open connections."),
Expand Down
43 changes: 30 additions & 13 deletions rabbitClient.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package main

import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"time"

Expand All @@ -10,7 +13,7 @@ import (

var client = &http.Client{Timeout: 10 * time.Second}

func loadMetrics(config rabbitExporterConfig, endpoint string, build func(d *json.Decoder)) {
func loadMetrics(config rabbitExporterConfig, endpoint string) (*json.Decoder, error) {
req, err := http.NewRequest("GET", config.RabbitURL+"/api/"+endpoint, nil)
req.SetBasicAuth(config.RabbitUsername, config.RabbitPassword)

Expand All @@ -22,24 +25,38 @@ func loadMetrics(config rabbitExporterConfig, endpoint string, build func(d *jso
status = resp.StatusCode
}
log.WithFields(log.Fields{"error": err, "host": config.RabbitURL, "statusCode": status}).Error("Error while retrieving data from rabbitHost")
return
return nil, errors.New("Error while retrieving data from rabbitHost")
}
build(json.NewDecoder(resp.Body))

body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, err
}

return json.NewDecoder(bytes.NewBuffer(body)), nil
}

func getQueueInfo(config rabbitExporterConfig) []QueueInfo {
func getQueueInfo(config rabbitExporterConfig) ([]QueueInfo, error) {
var q []QueueInfo
loadMetrics(config, "queues", func(d *json.Decoder) {
q = MakeQueueInfo(d)
})
return q

d, err := loadMetrics(config, "queues")
if err != nil {
return q, err
}

q = MakeQueueInfo(d)

return q, nil
}

func getOverviewMap(config rabbitExporterConfig) MetricMap {
func getOverviewMap(config rabbitExporterConfig) (MetricMap, error) {
var overview MetricMap
loadMetrics(config, "overview", func(d *json.Decoder) {
overview = MakeMap(d)
})
return overview

d, err := loadMetrics(config, "overview")
if err != nil {
return overview, err
}

return MakeMap(d), nil
}
8 changes: 4 additions & 4 deletions rabbitClient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestOverview(t *testing.T) {
RabbitURL: server.URL,
}

overview := getOverviewMap(*config)
overview, _ := getOverviewMap(*config)

expect(t, len(overview), 2)
expect(t, overview["float1"], 1.23456789101112)
Expand All @@ -45,7 +45,7 @@ func TestOverview(t *testing.T) {
RabbitURL: errorServer.URL,
}

overview = getOverviewMap(*config)
overview, _ = getOverviewMap(*config)

expect(t, len(overview), 0)
}
Expand All @@ -59,7 +59,7 @@ func TestQueues(t *testing.T) {
RabbitURL: server.URL,
}

queues := getQueueInfo(*config)
queues, _ := getQueueInfo(*config)
expect(t, len(queues), 2)
expect(t, queues[0].name, "Queue1")
expect(t, queues[0].vhost, "")
Expand All @@ -80,7 +80,7 @@ func TestQueues(t *testing.T) {
RabbitURL: errorServer.URL,
}

queues = getQueueInfo(*config)
queues, _ = getQueueInfo(*config)

expect(t, len(queues), 0)
}

0 comments on commit b6958bc

Please sign in to comment.