Skip to content

Commit

Permalink
add: CollectAndFormat to testutil
Browse files Browse the repository at this point in the history
CollectAndFormat is a helper function that returns the formatted metrics
to the caller, allowing them to use it how they want. This is different
to CollectAndCompare where the comparison is done strictly on behalf of
the caller. Often it is more convenient to perform a simple substring
match on the formatted metric.

Signed-off-by: Jack Cassidy <j.cassidy45@gmail.com>
  • Loading branch information
jcass8695 committed Apr 29, 2024
1 parent 2f59eb2 commit f7c7c22
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
27 changes: 27 additions & 0 deletions prometheus/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,33 @@ func TransactionalGatherAndCompare(g prometheus.TransactionalGatherer, expected
return compareMetricFamilies(got, wanted, metricNames...)
}

// CollectAndFormat registers the provided Collector with a newly created pedantic Registry. It then calls Gather with
// that Registry and filters by the provided metricNames. It writes the gathered metrics to a bugger formatted according
// to the provided format argument
func CollectAndFormat(c prometheus.Collector, format expfmt.FormatType, metricNames ...string) (*bytes.Buffer, error) {
reg := prometheus.NewPedanticRegistry()
if err := reg.Register(c); err != nil {
return nil, fmt.Errorf("registering collector failed: %w", err)
}

gotFiltered, err := reg.Gather()
if err != nil {
return nil, fmt.Errorf("gathering metrics failed: %w", err)
}

gotFiltered = filterMetrics(gotFiltered, metricNames)

var gotFormatted bytes.Buffer
enc := expfmt.NewEncoder(&gotFormatted, expfmt.NewFormat(format))
for _, mf := range gotFiltered {
if err := enc.Encode(mf); err != nil {
return nil, fmt.Errorf("encoding gathered metrics failed: %w", err)
}
}

return &gotFormatted, nil
}

// convertReaderToMetricFamily would read from a io.Reader object and convert it to a slice of
// dto.MetricFamily.
func convertReaderToMetricFamily(reader io.Reader) ([]*dto.MetricFamily, error) {
Expand Down
32 changes: 32 additions & 0 deletions prometheus/testutil/testutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ package testutil

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

"github.com/prometheus/common/expfmt"

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

Expand Down Expand Up @@ -431,3 +434,32 @@ func TestCollectAndCount(t *testing.T) {
t.Errorf("unexpected metric count, got %d, want %d", got, want)
}
}

func TestCollectAndFormat(t *testing.T) {
const expected = `# HELP foo_bar A value that represents the number of bars in foo.
# TYPE foo_bar counter
foo_bar{fizz="bang"} 1
`
c := prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "foo_bar",
Help: "A value that represents the number of bars in foo.",
},
[]string{"fizz"},
)
c.WithLabelValues("bang").Inc()

got, err := CollectAndFormat(c, expfmt.TypeTextPlain, "foo_bar")
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

gotS, err := io.ReadAll(got)
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

if string(gotS) != expected {
t.Errorf("unexpected metric output, got %q, expected %q", string(gotS), expected)
}
}

0 comments on commit f7c7c22

Please sign in to comment.