Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

add custom metric types #23

Merged
merged 23 commits into from Aug 11, 2016
Commits
Jump to file or symbol
Failed to load files and symbols.
+164 −6
Split
Viewing a subset of changes. View all
View
@@ -497,6 +497,11 @@ func (c *PCPClient) writeMetrics() {
c.writeInstanceMetric(metric.PCPInstanceMetric)
wg.Done()
}(metric)
+ case *PCPGaugeVector:
+ go func(metric *PCPGaugeVector) {
+ c.writeInstanceMetric(metric.PCPInstanceMetric)
+ wg.Done()
+ }(metric)
}
}
View
@@ -1019,17 +1019,19 @@ func TestCounterVector(t *testing.T) {
c.MustStart()
defer c.MustStop()
+ var val int64
+
// Set
err = cv.Set(10, "m1")
if err != nil {
t.Errorf("cannot set an instance, error: %v", err)
}
- if val, verr := cv.Val("m1"); val != 10 {
+ if val, err = cv.Val("m1"); val != 10 {
t.Errorf("expected m.1[m1] to be 10, got %v", val)
- } else if verr != nil {
- t.Errorf("cannot retrieve m.1[m1] value, error: %v", err)
+ } else if err != nil {
+ t.Errorf("cannot retrieve m.1[m1] value, error: %v", err)
}
// Inc
@@ -1039,9 +1041,69 @@ func TestCounterVector(t *testing.T) {
t.Errorf("cannot inc an instance, error: %v", err)
}
- if val, verr := cv.Val("m2"); val != 12 {
+ if val, err = cv.Val("m2"); val != 12 {
+ t.Errorf("expected m.1[m2] to be 12, got %v", val)
+ } else if err != nil {
+ t.Errorf("cannot retrieve m.1[m2] value, error: %v", err)
+ }
+
+ // Up
+
+ cv.Up("m1")
+
+ if val, err = cv.Val("m1"); val != 11 {
+ t.Errorf("expected m.1[m1] to be 11, got %v", val)
+ } else if err != nil {
+ t.Errorf("cannot retrieve m.1[m1] value, error: %v", err)
+ }
+}
+
+func TestGaugeVector(t *testing.T) {
+ g, err := NewPCPGaugeVector(map[string]float64{
+ "m1": 1.2,
+ "m2": 2.4,
+ }, "m.1")
+
+ if err != nil {
+ t.Errorf("cannot create GaugeVector, error: %v", err)
+ return
+ }
+
+ c, err := NewPCPClient("c")
+ if err != nil {
+ t.Errorf("cannot create client, error: %v", err)
+ }
+
+ c.MustRegister(g)
+
+ c.MustStart()
+ defer c.MustStop()
+
+ var val float64
+
+ // Set
+
+ err = g.Set(10, "m1")
+ if err != nil {
+ t.Errorf("cannot set an instance, error: %v", err)
+ }
+
+ if val, err = g.Val("m1"); val != 10 {
+ t.Errorf("expected m.1[m1] to be 10, got %v", val)
+ } else if err != nil {
+ t.Errorf("cannot retrieve m.1[m1] value, error: %v", err)
+ }
+
+ // Inc
+
+ err = g.Inc(10, "m2")
+ if err != nil {
+ t.Errorf("cannot inc an instance, error: %v", err)
+ }
+
+ if val, err = g.Val("m2"); val != 12.4 {
t.Errorf("expected m.1[m2] to be 12, got %v", val)
- } else if verr != nil {
- t.Errorf("cannot retrieve m.1[m2] value, error: %v", err)
+ } else if err != nil {
+ t.Errorf("cannot retrieve m.1[m2] value, error: %v", err)
}
}
View
@@ -900,3 +900,94 @@ func (c *PCPCounterVector) MustInc(inc int64, instance string) {
func (c *PCPCounterVector) Up(instance string) { c.MustInc(1, instance) }
///////////////////////////////////////////////////////////////////////////////
+
+// GaugeVector defines a Gauge on multiple instances
+type GaugeVector interface {
+ Metric
+
+ Val(string) float64
+
+ Set(float64, string) error
+ MustSet(float64, string)
+
+ Inc(float64, string) error
+ MustInc(float64, string)
+
+ Dec(float64, string) error
+ MustDec(float64, string)
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// PCPGaugeVector implements a PCP counter vector
+type PCPGaugeVector struct {
+ *PCPInstanceMetric
+}
+
+// NewPCPGaugeVector creates a new instance of a PCPGaugeVector
+func NewPCPGaugeVector(values map[string]float64, name string, desc ...string) (*PCPGaugeVector, error) {
+ instances, i := make([]string, len(values)), 0
+ vals := make(map[string]interface{})
+ for k, v := range values {
+ instances[i] = k
+ i++
+ vals[k] = v
+ }
+
+ indomname := name + ".indom"
+ indom, err := NewPCPInstanceDomain(indomname, instances)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create indom, error: %v", err)
+ }
+
+ im, err := NewPCPInstanceMetric(vals, name, indom, DoubleType, InstantSemantics, OneUnit, desc...)
+ if err != nil {
+ return nil, err
+ }
+
+ return &PCPGaugeVector{im}, nil
+}
+
+// Val returns the value of a particular instance of PCPCounterVector
+func (g *PCPGaugeVector) Val(instance string) (float64, error) {
+ val, err := g.PCPInstanceMetric.ValInstance(instance)
+ if err != nil {
+ return 0, err
+ }
+ return val.(float64), nil
+}
+
+// Set sets the value of a particular instance of PCPCounterVector
+func (g *PCPGaugeVector) Set(val float64, instance string) error {
+ return g.PCPInstanceMetric.SetInstance(instance, val)
+}
+
+// MustSet panics if Set fails
+func (g *PCPGaugeVector) MustSet(val float64, instance string) {
+ if err := g.Set(val, instance); err != nil {
+ panic(err)
+ }
+}
+
+// Inc increments the value of a particular instance of PCPCounterVector
+func (g *PCPGaugeVector) Inc(inc float64, instance string) error {
+ v, err := g.Val(instance)
+ if err != nil {
+ return err
+ }
+
+ return g.Set(v+inc, instance)
+}
+
+// MustInc panics if Inc fails
+func (g *PCPGaugeVector) MustInc(inc float64, instance string) {
+ if err := g.Inc(inc, instance); err != nil {
+ panic(err)
+ }
+}
+
+// Dec increments the value of a particular instance of PCPCounterVector
+func (g *PCPGaugeVector) Dec(inc float64, instance string) error { return g.Inc(-inc, instance) }
+
+// MustDec panics if Dec fails
+func (g *PCPGaugeVector) MustDec(inc float64, instance string) { g.MustInc(-inc, instance) }