Skip to content

Commit

Permalink
[DEVOPS-694] Move metrics to root
Browse files Browse the repository at this point in the history
  • Loading branch information
Julio Chana committed Feb 19, 2018
1 parent 6b4f8f4 commit fd06bce
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 263 deletions.
10 changes: 10 additions & 0 deletions metrics/dummy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package metrics

// Dummy is a handy instnce of a dummy instrumenter, most of the times it will be used on tests.
var Dummy = &dummy{}

// dummy is a dummy implementation of Instrumenter.
type dummy struct{}

func (d *dummy) SetClusterOK(namespace string, name string) {}
func (d *dummy) SetClusterError(namespace string, name string) {}
78 changes: 78 additions & 0 deletions metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package metrics

import (
"net/http"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

const (
promNamespace = "redis_operator"
promControllerSubsystem = "controller"
)

// Instrumenter is the interface that will collect the metrics and has ability to send/expose those metrics.
type Instrumenter interface {
SetClusterOK(namespace string, name string)
SetClusterError(namespace string, name string)
}

// PromMetrics implements the instrumenter so the metrics can be managed by Prometheus.
type PromMetrics struct {
// Metrics fields.
clusterOK *prometheus.GaugeVec // clusterOk is the status of a cluster

// Instrumentation fields.
registry prometheus.Registerer
path string
mux *http.ServeMux
}

// NewPrometheusMetrics returns a new PromMetrics object.
func NewPrometheusMetrics(path string, mux *http.ServeMux) *PromMetrics {
// Create metrics.
clusterOK := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: promNamespace,
Subsystem: promControllerSubsystem,
Name: "cluster_ok",
Help: "Number of failover clusters managed by the operator.",
}, []string{"namespace", "name"})

// Create Prometheus registry, use this instead of the prometheus default registry.
// TODO: Do we need go default instrumentation bout the go process metrics?
promReg := prometheus.NewRegistry()

// Create the instance.
p := &PromMetrics{
clusterOK: clusterOK,

registry: promReg,
path: path,
mux: mux,
}

// Register metrics on prometheus.
p.register()

// Register prometheus handler so we can serve the metrics.
handler := promhttp.HandlerFor(promReg, promhttp.HandlerOpts{})
mux.Handle(path, handler)

return p
}

// register will register all the required prometheus metrics on the Prometheus collector.
func (p *PromMetrics) register() {
p.registry.MustRegister(p.clusterOK)
}

// SetClusterOK set the cluster status to OK
func (p *PromMetrics) SetClusterOK(namespace string, name string) {
p.clusterOK.WithLabelValues(namespace, name).Set(1)
}

// SetClusterError set the cluster status to Error
func (p *PromMetrics) SetClusterError(namespace string, name string) {
p.clusterOK.WithLabelValues(namespace, name).Set(0)
}
118 changes: 118 additions & 0 deletions metrics/metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package metrics_test

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"

"github.com/spotahome/redis-operator/metrics"
)

func TestPrometheusMetrics(t *testing.T) {

tests := []struct {
name string
addMetrics func(pm *metrics.PromMetrics)
expMetrics []string
expCode int
}{
{
name: "Setting OK should give an OK",
addMetrics: func(pm *metrics.PromMetrics) {
pm.SetClusterOK("testns", "test")
},
expMetrics: []string{
`redis_operator_controller_cluster_ok{name="test",namespace="testns"} 1`,
},
expCode: http.StatusOK,
},
{
name: "Setting Error should give an Error",
addMetrics: func(pm *metrics.PromMetrics) {
pm.SetClusterError("testns", "test")
},
expMetrics: []string{
`redis_operator_controller_cluster_ok{name="test",namespace="testns"} 0`,
},
expCode: http.StatusOK,
},
{
name: "Setting Error after ok should give an Error",
addMetrics: func(pm *metrics.PromMetrics) {
pm.SetClusterOK("testns", "test")
pm.SetClusterError("testns", "test")
},
expMetrics: []string{
`redis_operator_controller_cluster_ok{name="test",namespace="testns"} 0`,
},
expCode: http.StatusOK,
},
{
name: "Setting OK after Error should give an OK",
addMetrics: func(pm *metrics.PromMetrics) {
pm.SetClusterError("testns", "test")
pm.SetClusterOK("testns", "test")
},
expMetrics: []string{
`redis_operator_controller_cluster_ok{name="test",namespace="testns"} 1`,
},
expCode: http.StatusOK,
},
{
name: "Multiple clusters should appear",
addMetrics: func(pm *metrics.PromMetrics) {
pm.SetClusterOK("testns", "test")
pm.SetClusterOK("testns", "test2")
},
expMetrics: []string{
`redis_operator_controller_cluster_ok{name="test",namespace="testns"} 1`,
`redis_operator_controller_cluster_ok{name="test2",namespace="testns"} 1`,
},
expCode: http.StatusOK,
},
{
name: "Same name on different namespaces should appear",
addMetrics: func(pm *metrics.PromMetrics) {
pm.SetClusterOK("testns1", "test")
pm.SetClusterOK("testns2", "test")
},
expMetrics: []string{
`redis_operator_controller_cluster_ok{name="test",namespace="testns1"} 1`,
`redis_operator_controller_cluster_ok{name="test",namespace="testns2"} 1`,
},
expCode: http.StatusOK,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert := assert.New(t)

path := "/awesome-metrics"

// Create the muxer for testing.
mx := http.NewServeMux()
pm := metrics.NewPrometheusMetrics(path, mx)

// Add metrics to prometheus.
test.addMetrics(pm)

// Make the request to the metrics.
req := httptest.NewRequest("GET", path, nil)
w := httptest.NewRecorder()
mx.ServeHTTP(w, req)

resp := w.Result()
if assert.Equal(test.expCode, resp.StatusCode) {
body, _ := ioutil.ReadAll(resp.Body)
// Check all the metrics are present.
for _, expMetric := range test.expMetrics {
assert.Contains(string(body), expMetric)
}
}
})
}
}
15 changes: 0 additions & 15 deletions pkg/metrics/dummy.go

This file was deleted.

144 changes: 0 additions & 144 deletions pkg/metrics/metrics.go

This file was deleted.

Loading

0 comments on commit fd06bce

Please sign in to comment.