Refactor gauge api with options. (#1086)
* Refactor gauge api with options.
* fixed review comments.
diff --git a/metric/examples_test.go b/metric/examples_test.go
index cc39571..c4b2e0a 100644
--- a/metric/examples_test.go
+++ b/metric/examples_test.go
@@ -25,7 +25,10 @@
r := metric.NewRegistry()
// TODO: allow exporting from a registry
- g, _ := r.AddInt64Gauge("active_request", "Number of active requests, per method.", metricdata.UnitDimensionless, "method")
+ g, _ := r.AddInt64Gauge("active_request",
+ metric.WithDescription("Number of active requests, per method."),
+ metric.WithUnit(metricdata.UnitDimensionless),
+ metric.WithLabelKeys("method"))
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
e, _ := g.GetEntry(metricdata.NewLabelValue(request.Method))
diff --git a/metric/gauge_test.go b/metric/gauge_test.go
index b451f57..8ed358b 100644
--- a/metric/gauge_test.go
+++ b/metric/gauge_test.go
@@ -26,7 +26,9 @@
func TestGauge(t *testing.T) {
r := NewRegistry()
- f, _ := r.AddFloat64Gauge("TestGauge", "", "", "k1", "k2")
+
+ f, _ := r.AddFloat64Gauge("TestGauge",
+ WithLabelKeys("k1", "k2"))
e, _ := f.GetEntry(metricdata.LabelValue{}, metricdata.LabelValue{})
e.Set(5)
e, _ = f.GetEntry(metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
@@ -81,16 +83,15 @@
}
func TestGaugeMetricDescriptor(t *testing.T) {
- unit := metricdata.UnitDimensionless
r := NewRegistry()
- gf, _ := r.AddFloat64Gauge("float64_gauge", "", unit)
+ gf, _ := r.AddFloat64Gauge("float64_gauge")
compareType(gf.g.desc.Type, metricdata.TypeGaugeFloat64, t)
- gi, _ := r.AddInt64Gauge("int64_gauge", "", unit)
+ gi, _ := r.AddInt64Gauge("int64_gauge")
compareType(gi.g.desc.Type, metricdata.TypeGaugeInt64, t)
- dgf, _ := r.AddFloat64DerivedGauge("derived_float64_gauge", "", unit)
+ dgf, _ := r.AddFloat64DerivedGauge("derived_float64_gauge")
compareType(dgf.g.desc.Type, metricdata.TypeGaugeFloat64, t)
- dgi, _ := r.AddInt64DerivedGauge("derived_int64_gauge", "", unit)
+ dgi, _ := r.AddInt64DerivedGauge("derived_int64_gauge")
compareType(dgi.g.desc.Type, metricdata.TypeGaugeInt64, t)
}
@@ -100,9 +101,68 @@
}
}
+func TestGaugeMetricOptionDesc(t *testing.T) {
+ r := NewRegistry()
+ name := "testOptDesc"
+ gf, _ := r.AddFloat64Gauge(name, WithDescription("test"))
+ want := metricdata.Descriptor{
+ Name: name,
+ Description: "test",
+ Type: metricdata.TypeGaugeFloat64,
+ }
+ got := gf.g.desc
+ if !cmp.Equal(got, want) {
+ t.Errorf("metric option description: got %v, want %v\n", got, want)
+ }
+}
+
+func TestGaugeMetricOptionUnit(t *testing.T) {
+ r := NewRegistry()
+ name := "testOptUnit"
+ gf, _ := r.AddFloat64Gauge(name, WithUnit(metricdata.UnitMilliseconds))
+ want := metricdata.Descriptor{
+ Name: name,
+ Unit: metricdata.UnitMilliseconds,
+ Type: metricdata.TypeGaugeFloat64,
+ }
+ got := gf.g.desc
+ if !cmp.Equal(got, want) {
+ t.Errorf("metric descriptor: got %v, want %v\n", got, want)
+ }
+}
+
+func TestGaugeMetricOptionLabelKeys(t *testing.T) {
+ r := NewRegistry()
+ name := "testOptUnit"
+ gf, _ := r.AddFloat64Gauge(name, WithLabelKeys("k1", "k3"))
+ want := metricdata.Descriptor{
+ Name: name,
+ LabelKeys: []string{"k1", "k3"},
+ Type: metricdata.TypeGaugeFloat64,
+ }
+ got := gf.g.desc
+ if !cmp.Equal(got, want) {
+ t.Errorf("metric descriptor: got %v, want %v\n", got, want)
+ }
+}
+
+func TestGaugeMetricOptionDefault(t *testing.T) {
+ r := NewRegistry()
+ name := "testOptUnit"
+ gf, _ := r.AddFloat64Gauge(name)
+ want := metricdata.Descriptor{
+ Name: name,
+ Type: metricdata.TypeGaugeFloat64,
+ }
+ got := gf.g.desc
+ if !cmp.Equal(got, want) {
+ t.Errorf("metric descriptor: got %v, want %v\n", got, want)
+ }
+}
+
func TestFloat64Entry_Add(t *testing.T) {
r := NewRegistry()
- g, _ := r.AddFloat64Gauge("g", "", metricdata.UnitDimensionless)
+ g, _ := r.AddFloat64Gauge("g")
e, _ := g.GetEntry()
e.Add(0)
ms := r.Read()
@@ -125,7 +185,7 @@
func TestFloat64Gauge_Add_NegativeTotals(t *testing.T) {
r := NewRegistry()
- g, _ := r.AddFloat64Gauge("g", "", metricdata.UnitDimensionless)
+ g, _ := r.AddFloat64Gauge("g")
e, _ := g.GetEntry()
e.Add(-1.0)
ms := r.Read()
@@ -136,7 +196,7 @@
func TestInt64GaugeEntry_Add(t *testing.T) {
r := NewRegistry()
- g, _ := r.AddInt64Gauge("g", "", metricdata.UnitDimensionless)
+ g, _ := r.AddInt64Gauge("g")
e, _ := g.GetEntry()
e.Add(0)
ms := r.Read()
@@ -153,7 +213,7 @@
func TestInt64Gauge_Add_NegativeTotals(t *testing.T) {
r := NewRegistry()
- g, _ := r.AddInt64Gauge("g", "", metricdata.UnitDimensionless)
+ g, _ := r.AddInt64Gauge("g")
e, _ := g.GetEntry()
e.Add(-1)
ms := r.Read()
@@ -164,16 +224,16 @@
func TestGaugeWithSameNameDiffType(t *testing.T) {
r := NewRegistry()
- r.AddInt64Gauge("g", "", metricdata.UnitDimensionless)
- _, gotErr := r.AddFloat64Gauge("g", "", metricdata.UnitDimensionless)
+ r.AddInt64Gauge("g")
+ _, gotErr := r.AddFloat64Gauge("g")
if gotErr == nil {
t.Errorf("got: nil, want error: %v", errGaugeExistsWithDiffType)
}
- _, gotErr = r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless)
+ _, gotErr = r.AddInt64DerivedGauge("g")
if gotErr == nil {
t.Errorf("got: nil, want error: %v", errGaugeExistsWithDiffType)
}
- _, gotErr = r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless)
+ _, gotErr = r.AddFloat64DerivedGauge("g")
if gotErr == nil {
t.Errorf("got: nil, want error: %v", errGaugeExistsWithDiffType)
}
@@ -181,7 +241,7 @@
func TestGaugeWithLabelMismatch(t *testing.T) {
r := NewRegistry()
- g, _ := r.AddInt64Gauge("g", "", metricdata.UnitDimensionless, "k1")
+ g, _ := r.AddInt64Gauge("g", WithLabelKeys("k1"))
_, gotErr := g.GetEntry(metricdata.NewLabelValue("k1v2"), metricdata.NewLabelValue("k2v2"))
if gotErr == nil {
t.Errorf("got: nil, want error: %v", errKeyValueMismatch)
@@ -222,7 +282,7 @@
for i := 0; i < 5; i++ {
go func(k int) {
for j := 0; j < 5; j++ {
- g, _ := r.AddInt64Gauge(fmt.Sprintf("g%d%d", k, j), "", metricdata.UnitDimensionless)
+ g, _ := r.AddInt64Gauge(fmt.Sprintf("g%d%d", k, j))
e, _ := g.GetEntry()
e.Add(1)
}
@@ -272,7 +332,7 @@
func TestInt64DerivedGaugeEntry_Add(t *testing.T) {
r := NewRegistry()
q := &queueInt64{3}
- g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddInt64DerivedGauge("g", WithLabelKeys("k1", "k2"))
err := g.UpsertEntry(q.ToInt64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
if err != nil {
t.Errorf("want: nil, got: %v", err)
@@ -290,7 +350,7 @@
func TestInt64DerivedGaugeEntry_AddWithNilObj(t *testing.T) {
r := NewRegistry()
- g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddInt64DerivedGauge("g", WithLabelKeys("k1", "k2"))
gotErr := g.UpsertEntry(nil, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
if gotErr == nil {
t.Errorf("expected error but got nil")
@@ -300,7 +360,7 @@
func TestInt64DerivedGaugeEntry_AddWithInvalidLabels(t *testing.T) {
r := NewRegistry()
q := &queueInt64{3}
- g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddInt64DerivedGauge("g", WithLabelKeys("k1", "k2"))
gotErr := g.UpsertEntry(q.ToInt64, metricdata.NewLabelValue("k1v1"))
if gotErr == nil {
t.Errorf("expected error but got nil")
@@ -311,7 +371,7 @@
r := NewRegistry()
q := &queueInt64{3}
q2 := &queueInt64{5}
- g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddInt64DerivedGauge("g", WithLabelKeys("k1", "k2"))
g.UpsertEntry(q.ToInt64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
gotErr := g.UpsertEntry(q2.ToInt64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
if gotErr != nil {
@@ -334,7 +394,7 @@
func TestFloat64DerivedGaugeEntry_Add(t *testing.T) {
r := NewRegistry()
q := &queueFloat64{5.0}
- g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddFloat64DerivedGauge("g", WithLabelKeys("k1", "k2"))
err := g.UpsertEntry(q.ToFloat64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
if err != nil {
t.Errorf("want: nil, got: %v", err)
@@ -352,7 +412,7 @@
func TestFloat64DerivedGaugeEntry_AddWithNilObj(t *testing.T) {
r := NewRegistry()
- g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddFloat64DerivedGauge("g", WithLabelKeys("k1", "k2"))
gotErr := g.UpsertEntry(nil, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
if gotErr == nil {
t.Errorf("expected error but got nil")
@@ -362,7 +422,7 @@
func TestFloat64DerivedGaugeEntry_AddWithInvalidLabels(t *testing.T) {
r := NewRegistry()
q := &queueFloat64{3}
- g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddFloat64DerivedGauge("g", WithLabelKeys("k1", "k2"))
gotErr := g.UpsertEntry(q.ToFloat64, metricdata.NewLabelValue("k1v1"))
if gotErr == nil {
t.Errorf("expected error but got nil")
@@ -373,7 +433,7 @@
r := NewRegistry()
q := &queueFloat64{3.0}
q2 := &queueFloat64{5.0}
- g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
+ g, _ := r.AddFloat64DerivedGauge("g", WithLabelKeys("k1", "k2"))
g.UpsertEntry(q.ToFloat64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
gotErr := g.UpsertEntry(q2.ToFloat64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
if gotErr != nil {
diff --git a/metric/metricexport/reader_test.go b/metric/metricexport/reader_test.go
index a043530..7567924 100644
--- a/metric/metricexport/reader_test.go
+++ b/metric/metricexport/reader_test.go
@@ -53,7 +53,10 @@
func init() {
r := metric.NewRegistry()
metricproducer.GlobalManager().AddProducer(r)
- g, _ := r.AddInt64Gauge("active_request", "Number of active requests, per method.", metricdata.UnitDimensionless, "method")
+ g, _ := r.AddInt64Gauge("active_request",
+ metric.WithDescription("Number of active requests, per method."),
+ metric.WithUnit(metricdata.UnitDimensionless),
+ metric.WithLabelKeys("method"))
gaugeEntry, _ = g.GetEntry(metricdata.NewLabelValue("foo"))
}
diff --git a/metric/registry.go b/metric/registry.go
index 6181f45..80df542 100644
--- a/metric/registry.go
+++ b/metric/registry.go
@@ -37,19 +37,50 @@
derivedGaugeFloat64
)
+//TODO: [rghetia] add constant labels.
+type metricOptions struct {
+ unit metricdata.Unit
+ labelkeys []string
+ desc string
+}
+
+// Options apply changes to metricOptions.
+type Options func(*metricOptions)
+
+// WithDescription applies provided description.
+func WithDescription(desc string) Options {
+ return func(mo *metricOptions) {
+ mo.desc = desc
+ }
+}
+
+// WithUnit applies provided unit.
+func WithUnit(unit metricdata.Unit) Options {
+ return func(mo *metricOptions) {
+ mo.unit = unit
+ }
+}
+
+// WithLabelKeys applies provided label.
+func WithLabelKeys(labelKeys ...string) Options {
+ return func(mo *metricOptions) {
+ mo.labelkeys = labelKeys
+ }
+}
+
// NewRegistry initializes a new Registry.
func NewRegistry() *Registry {
return &Registry{}
}
// AddFloat64Gauge creates and adds a new float64-valued gauge to this registry.
-func (r *Registry) AddFloat64Gauge(name, description string, unit metricdata.Unit, labelKeys ...string) (*Float64Gauge, error) {
+func (r *Registry) AddFloat64Gauge(name string, mos ...Options) (*Float64Gauge, error) {
f := &Float64Gauge{
g: gauge{
gType: gaugeFloat64,
},
}
- _, err := r.initGauge(&f.g, labelKeys, name, description, unit)
+ _, err := r.initGauge(&f.g, name, mos...)
if err != nil {
return nil, err
}
@@ -57,13 +88,13 @@
}
// AddInt64Gauge creates and adds a new int64-valued gauge to this registry.
-func (r *Registry) AddInt64Gauge(name, description string, unit metricdata.Unit, labelKeys ...string) (*Int64Gauge, error) {
+func (r *Registry) AddInt64Gauge(name string, mos ...Options) (*Int64Gauge, error) {
i := &Int64Gauge{
g: gauge{
gType: gaugeInt64,
},
}
- _, err := r.initGauge(&i.g, labelKeys, name, description, unit)
+ _, err := r.initGauge(&i.g, name, mos...)
if err != nil {
return nil, err
}
@@ -73,13 +104,13 @@
// AddInt64DerivedGauge creates and adds a new derived int64-valued gauge to this registry.
// A derived gauge is convenient form of gauge where the object associated with the gauge
// provides its value by implementing func() int64.
-func (r *Registry) AddInt64DerivedGauge(name, description string, unit metricdata.Unit, labelKeys ...string) (*Int64DerivedGauge, error) {
+func (r *Registry) AddInt64DerivedGauge(name string, mos ...Options) (*Int64DerivedGauge, error) {
i := &Int64DerivedGauge{
g: gauge{
gType: derivedGaugeInt64,
},
}
- _, err := r.initGauge(&i.g, labelKeys, name, description, unit)
+ _, err := r.initGauge(&i.g, name, mos...)
if err != nil {
return nil, err
}
@@ -89,13 +120,13 @@
// AddFloat64DerivedGauge creates and adds a new derived float64-valued gauge to this registry.
// A derived gauge is convenient form of gauge where the object associated with the gauge
// provides its value by implementing func() float64.
-func (r *Registry) AddFloat64DerivedGauge(name, description string, unit metricdata.Unit, labelKeys ...string) (*Float64DerivedGauge, error) {
+func (r *Registry) AddFloat64DerivedGauge(name string, mos ...Options) (*Float64DerivedGauge, error) {
f := &Float64DerivedGauge{
g: gauge{
gType: derivedGaugeFloat64,
},
}
- _, err := r.initGauge(&f.g, labelKeys, name, description, unit)
+ _, err := r.initGauge(&f.g, name, mos...)
if err != nil {
return nil, err
}
@@ -117,7 +148,15 @@
}
}
-func (r *Registry) initGauge(g *gauge, labelKeys []string, name string, description string, unit metricdata.Unit) (*gauge, error) {
+func createMetricOption(mos ...Options) *metricOptions {
+ o := &metricOptions{}
+ for _, mo := range mos {
+ mo(o)
+ }
+ return o
+}
+
+func (r *Registry) initGauge(g *gauge, name string, mos ...Options) (*gauge, error) {
val, ok := r.gauges.Load(name)
if ok {
existing := val.(*gauge)
@@ -125,13 +164,14 @@
return nil, errGaugeExistsWithDiffType
}
}
- g.keys = labelKeys
g.start = time.Now()
+ o := createMetricOption(mos...)
+ g.keys = o.labelkeys
g.desc = metricdata.Descriptor{
Name: name,
- Description: description,
- Unit: unit,
- LabelKeys: labelKeys,
+ Description: o.desc,
+ Unit: o.unit,
+ LabelKeys: o.labelkeys,
Type: gTypeToMetricType(g),
}
r.gauges.Store(name, g)