Skip to content

Commit

Permalink
Merge pull request #28 from AntonRutkevich/parametrize-prometheus-metric
Browse files Browse the repository at this point in the history
Add ability to parametrize prometheus metric name
  • Loading branch information
hexdigest authored Aug 4, 2020
2 parents c4e12ab + d900744 commit e3ff801
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 2 deletions.
5 changes: 3 additions & 2 deletions templates/prometheus
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
)

{{ $decorator := (or .Vars.DecoratorName (printf "%sWithPrometheus" .Interface.Name)) }}
{{ $metric_name := (or .Vars.MetricName (printf "%s_duration_seconds" (down .Interface.Name))) }}

// {{$decorator}} implements {{.Interface.Type}} interface with all methods wrapped
// with Prometheus metrics
Expand All @@ -16,8 +17,8 @@ type {{$decorator}} struct {

var {{down .Interface.Name}}DurationSummaryVec = promauto.NewSummaryVec(
prometheus.SummaryOpts{
Name: "{{down .Interface.Name}}_duration_seconds",
Help: "{{down .Interface.Name}} runtime duration and result",
Name: "{{$metric_name}}",
Help: "{{ down .Interface.Name }} runtime duration and result",
MaxAge: time.Minute,
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
},
Expand Down
8 changes: 8 additions & 0 deletions templates_tests/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ type TestInterface interface {
NoParamsOrResults()
Channels(chA chan bool, chB chan<- bool, chanC <-chan bool)
}

// AnotherTestInterface is used to test templates where TestInterface was already used
type AnotherTestInterface interface {
F(ctx context.Context, a1 string, a2 ...string) (result1, result2 string, err error)
NoError(string) string
NoParamsOrResults()
Channels(chA chan bool, chB chan<- bool, chanC <-chan bool)
}
85 changes: 85 additions & 0 deletions templates_tests/interface_with_prometheus_metric_name.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package templatestests

// DO NOT EDIT!
// This code is generated with http://github.com/hexdigest/gowrap tool
// using ../templates/prometheus template

//go:generate gowrap gen -p github.com/hexdigest/gowrap/templates_tests -i AnotherTestInterface -t ../templates/prometheus -o interface_with_prometheus_metric_name.go -v MetricName=custom_metric_name_seconds

import (
"context"
"time"

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

// AnotherTestInterfaceWithPrometheus implements AnotherTestInterface interface with all methods wrapped
// with Prometheus metrics
type AnotherTestInterfaceWithPrometheus struct {
base AnotherTestInterface
instanceName string
}

var anothertestinterfaceDurationSummaryVec = promauto.NewSummaryVec(
prometheus.SummaryOpts{
Name: "custom_metric_name_seconds",
Help: "anothertestinterface runtime duration and result",
MaxAge: time.Minute,
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
},
[]string{"instance_name", "method", "result"})

// NewAnotherTestInterfaceWithPrometheus returns an instance of the AnotherTestInterface decorated with prometheus summary metric
func NewAnotherTestInterfaceWithPrometheus(base AnotherTestInterface, instanceName string) AnotherTestInterfaceWithPrometheus {
return AnotherTestInterfaceWithPrometheus{
base: base,
instanceName: instanceName,
}
}

// Channels implements AnotherTestInterface
func (_d AnotherTestInterfaceWithPrometheus) Channels(chA chan bool, chB chan<- bool, chanC <-chan bool) {
_since := time.Now()
defer func() {
result := "ok"
anothertestinterfaceDurationSummaryVec.WithLabelValues(_d.instanceName, "Channels", result).Observe(time.Since(_since).Seconds())
}()
_d.base.Channels(chA, chB, chanC)
return
}

// F implements AnotherTestInterface
func (_d AnotherTestInterfaceWithPrometheus) F(ctx context.Context, a1 string, a2 ...string) (result1 string, result2 string, err error) {
_since := time.Now()
defer func() {
result := "ok"
if err != nil {
result = "error"
}

anothertestinterfaceDurationSummaryVec.WithLabelValues(_d.instanceName, "F", result).Observe(time.Since(_since).Seconds())
}()
return _d.base.F(ctx, a1, a2...)
}

// NoError implements AnotherTestInterface
func (_d AnotherTestInterfaceWithPrometheus) NoError(s1 string) (s2 string) {
_since := time.Now()
defer func() {
result := "ok"
anothertestinterfaceDurationSummaryVec.WithLabelValues(_d.instanceName, "NoError", result).Observe(time.Since(_since).Seconds())
}()
return _d.base.NoError(s1)
}

// NoParamsOrResults implements AnotherTestInterface
func (_d AnotherTestInterfaceWithPrometheus) NoParamsOrResults() {
_since := time.Now()
defer func() {
result := "ok"
anothertestinterfaceDurationSummaryVec.WithLabelValues(_d.instanceName, "NoParamsOrResults", result).Observe(time.Since(_since).Seconds())
}()
_d.base.NoParamsOrResults()
return
}
33 changes: 33 additions & 0 deletions templates_tests/interface_with_prometheus_metric_name_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package templatestests

import (
"context"
"errors"
"testing"

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

func TestTestInterfaceWithPrometheusMetricName_F(t *testing.T) {
t.Run("no error", func(t *testing.T) {
impl := &testImpl{r1: "1", r2: "2"}

wrapped := NewAnotherTestInterfaceWithPrometheus(impl, "test")
r1, r2, err := wrapped.F(context.Background(), "a1", "a2")

assert.NoError(t, err)
assert.Equal(t, "1", r1)
assert.Equal(t, "2", r2)
})

t.Run("with error", func(t *testing.T) {
impl := &testImpl{r1: "1", r2: "2", err: errors.New("unexpected error")}

wrapped := NewAnotherTestInterfaceWithPrometheus(impl, "test")
r1, r2, err := wrapped.F(context.Background(), "a1", "a2")

assert.Error(t, err)
assert.Equal(t, "1", r1)
assert.Equal(t, "2", r2)
})
}

0 comments on commit e3ff801

Please sign in to comment.