Skip to content

Commit

Permalink
Metrics: Add push client to push metrics to endpoint
Browse files Browse the repository at this point in the history
Creates a push client that will be used to push metrics to
Prometheus Aggregation Gateway. The aggregation gateway expects
a specific query path to push the metrics to and hence a client is
created which will format the metrics as per the aggregation gateway's
requirement.

Also added extra helper functions that will be used by the metrics API
to push to the gateway.
  • Loading branch information
rna-afk committed Jul 2, 2020
1 parent 5face7c commit 0604264
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 1 deletion.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ require (
github.com/pierrec/lz4 v2.3.0+incompatible // indirect
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.10.1
github.com/prometheus/client_golang v1.2.1 // indirect
github.com/prometheus/client_golang v1.2.1
github.com/prometheus/common v0.7.0
github.com/prometheus/procfs v0.0.8 // indirect
github.com/satori/uuid v1.2.0 // indirect
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
Expand Down
38 changes: 38 additions & 0 deletions pkg/metrics/pushclient/pushclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package pushclient

import (
"net/http"

"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/push"
"github.com/prometheus/common/expfmt"
)

// gatewayURL is the default url that will be used as the endpoint to push to.
// To push to a centralized prometheus aggregation gateway, change this url.
var gatewayURL = "http://localhost:9092"

// pushAllToAggregationGateway is a helper that takes care of the actual code that pushes to the prometheus
// aggregation gateway. It takes a list of collectors and pushes all of them to the desired url.
func pushAllToAggregationGateway(url string, client push.HTTPDoer, collectors ...prometheus.Collector) error {
allJobsName := "installer_metrics"
pushClient := push.New(url, allJobsName).Client(client).Format(expfmt.FmtText)

for _, value := range collectors {
pushClient.Collector(value)
}

err := pushClient.Push()
if err != nil {
return errors.Wrap(err, "failed to push metrics")
}
return nil
}

// Push calls the pushAllToAggregationGateway for the all metrics.
// This function acts as a re-router which currently pushes to the aggregation gateway.
// Any change in gateway logic can be written here to route the metrics.
func Push(collectors ...prometheus.Collector) error {
return pushAllToAggregationGateway(gatewayURL, &http.Client{}, collectors...)
}
94 changes: 94 additions & 0 deletions pkg/metrics/pushclient/pushclient_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package pushclient

import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"

"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
)

func TestPushMetricsToGateway(t *testing.T) {
promCollector := prometheus.NewCounter(
prometheus.CounterOpts{
Name: "test",
Help: "test metrics",
ConstLabels: map[string]string{"test1": "test1"},
},
)

promCollector.Add(10)

expectedOutput := `# HELP test test metrics
# TYPE test counter
test{test1="test1"} 10
`

testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
buf := new(strings.Builder)
_, err := io.Copy(buf, req.Body)
assert.NoError(t, err)
assert.EqualValues(t, expectedOutput, buf.String())
fmt.Println("all done")
}))
defer testServer.Close()
pushAllToAggregationGateway(testServer.URL, &aggregationClient{&http.Client{}}, promCollector)

}

func TestPushMetricsToAllGateway(t *testing.T) {
counter := prometheus.NewCounter(
prometheus.CounterOpts{
Name: "test_counter",
Help: "test metrics",
ConstLabels: map[string]string{"test1": "test1"},
},
)
counter.Add(10)

histogram := prometheus.NewHistogram(
prometheus.HistogramOpts{
Name: "test_histogram",
Help: "test metrics",
ConstLabels: map[string]string{"test1": "test1"},
},
)
histogram.Observe(10)

promCollector := []prometheus.Collector{counter, histogram}

expectedOutput := `# HELP test_counter test metrics
# TYPE test_counter counter
test_counter{test1="test1"} 10
# HELP test_histogram test metrics
# TYPE test_histogram histogram
test_histogram_bucket{test1="test1",le="0.005"} 0
test_histogram_bucket{test1="test1",le="0.01"} 0
test_histogram_bucket{test1="test1",le="0.025"} 0
test_histogram_bucket{test1="test1",le="0.05"} 0
test_histogram_bucket{test1="test1",le="0.1"} 0
test_histogram_bucket{test1="test1",le="0.25"} 0
test_histogram_bucket{test1="test1",le="0.5"} 0
test_histogram_bucket{test1="test1",le="1"} 0
test_histogram_bucket{test1="test1",le="2.5"} 0
test_histogram_bucket{test1="test1",le="5"} 0
test_histogram_bucket{test1="test1",le="10"} 1
test_histogram_bucket{test1="test1",le="+Inf"} 1
test_histogram_sum{test1="test1"} 10
test_histogram_count{test1="test1"} 1
`

testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
buf := new(strings.Builder)
_, err := io.Copy(buf, req.Body)
assert.NoError(t, err)
assert.EqualValues(t, expectedOutput, buf.String())
fmt.Println("all done")
}))
defer testServer.Close()
pushAllToAggregationGateway(testServer.URL, &aggregationClient{&http.Client{}}, promCollector...)
}

0 comments on commit 0604264

Please sign in to comment.