initial import

This commit is contained in:
kevin
2020-07-26 17:09:05 +08:00
commit 7e3a369a8f
647 changed files with 54754 additions and 0 deletions

55
core/metric/counter.go Normal file
View File

@@ -0,0 +1,55 @@
package metric
import (
"zero/core/proc"
prom "github.com/prometheus/client_golang/prometheus"
)
type (
CounterVecOpts VectorOpts
CounterVec interface {
Inc(lables ...string)
Add(v float64, labels ...string)
close() bool
}
promCounterVec struct {
counter *prom.CounterVec
}
)
func NewCounterVec(cfg *CounterVecOpts) CounterVec {
if cfg == nil {
return nil
}
vec := prom.NewCounterVec(prom.CounterOpts{
Namespace: cfg.Namespace,
Subsystem: cfg.Subsystem,
Name: cfg.Name,
Help: cfg.Help,
}, cfg.Labels)
prom.MustRegister(vec)
cv := &promCounterVec{
counter: vec,
}
proc.AddShutdownListener(func() {
cv.close()
})
return cv
}
func (cv *promCounterVec) Inc(labels ...string) {
cv.counter.WithLabelValues(labels...).Inc()
}
func (cv *promCounterVec) Add(v float64, lables ...string) {
cv.counter.WithLabelValues(lables...).Add(v)
}
func (cv *promCounterVec) close() bool {
return prom.Unregister(cv.counter)
}

View File

@@ -0,0 +1,53 @@
package metric
import (
"testing"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
)
func TestNewCounterVec(t *testing.T) {
counterVec := NewCounterVec(&CounterVecOpts{
Namespace: "http_server",
Subsystem: "requests",
Name: "total",
Help: "rpc client requests error count.",
})
defer counterVec.close()
counterVecNil := NewCounterVec(nil)
assert.NotNil(t, counterVec)
assert.Nil(t, counterVecNil)
}
func TestCounterIncr(t *testing.T) {
counterVec := NewCounterVec(&CounterVecOpts{
Namespace: "http_client",
Subsystem: "call",
Name: "code_total",
Help: "http client requests error count.",
Labels: []string{"path", "code"},
})
defer counterVec.close()
cv, _ := counterVec.(*promCounterVec)
cv.Inc("/Users", "500")
cv.Inc("/Users", "500")
r := testutil.ToFloat64(cv.counter)
assert.Equal(t, float64(2), r)
}
func TestCounterAdd(t *testing.T) {
counterVec := NewCounterVec(&CounterVecOpts{
Namespace: "rpc_server",
Subsystem: "requests",
Name: "err_total",
Help: "rpc client requests error count.",
Labels: []string{"method", "code"},
})
defer counterVec.close()
cv, _ := counterVec.(*promCounterVec)
cv.Add(11, "/Users", "500")
cv.Add(22, "/Users", "500")
r := testutil.ToFloat64(cv.counter)
assert.Equal(t, float64(33), r)
}

61
core/metric/gauge.go Normal file
View File

@@ -0,0 +1,61 @@
package metric
import (
"zero/core/proc"
prom "github.com/prometheus/client_golang/prometheus"
)
type (
GaugeVecOpts VectorOpts
GuageVec interface {
Set(v float64, labels ...string)
Inc(labels ...string)
Add(v float64, labels ...string)
close() bool
}
promGuageVec struct {
gauge *prom.GaugeVec
}
)
func NewGaugeVec(cfg *GaugeVecOpts) GuageVec {
if cfg == nil {
return nil
}
vec := prom.NewGaugeVec(
prom.GaugeOpts{
Namespace: cfg.Namespace,
Subsystem: cfg.Subsystem,
Name: cfg.Name,
Help: cfg.Help,
}, cfg.Labels)
prom.MustRegister(vec)
gv := &promGuageVec{
gauge: vec,
}
proc.AddShutdownListener(func() {
gv.close()
})
return gv
}
func (gv *promGuageVec) Inc(labels ...string) {
gv.gauge.WithLabelValues(labels...).Inc()
}
func (gv *promGuageVec) Add(v float64, lables ...string) {
gv.gauge.WithLabelValues(lables...).Add(v)
}
func (gv *promGuageVec) Set(v float64, lables ...string) {
gv.gauge.WithLabelValues(lables...).Set(v)
}
func (gv *promGuageVec) close() bool {
return prom.Unregister(gv.gauge)
}

68
core/metric/gauge_test.go Normal file
View File

@@ -0,0 +1,68 @@
package metric
import (
"testing"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
)
func TestNewGaugeVec(t *testing.T) {
gaugeVec := NewGaugeVec(&GaugeVecOpts{
Namespace: "rpc_server",
Subsystem: "requests",
Name: "duration",
Help: "rpc server requests duration(ms).",
})
defer gaugeVec.close()
gaugeVecNil := NewGaugeVec(nil)
assert.NotNil(t, gaugeVec)
assert.Nil(t, gaugeVecNil)
}
func TestGaugeInc(t *testing.T) {
gaugeVec := NewGaugeVec(&GaugeVecOpts{
Namespace: "rpc_client2",
Subsystem: "requests",
Name: "duration_ms",
Help: "rpc server requests duration(ms).",
Labels: []string{"path"},
})
defer gaugeVec.close()
gv, _ := gaugeVec.(*promGuageVec)
gv.Inc("/users")
gv.Inc("/users")
r := testutil.ToFloat64(gv.gauge)
assert.Equal(t, float64(2), r)
}
func TestGaugeAdd(t *testing.T) {
gaugeVec := NewGaugeVec(&GaugeVecOpts{
Namespace: "rpc_client",
Subsystem: "request",
Name: "duration_ms",
Help: "rpc server requests duration(ms).",
Labels: []string{"path"},
})
defer gaugeVec.close()
gv, _ := gaugeVec.(*promGuageVec)
gv.Add(-10, "/classroom")
gv.Add(30, "/classroom")
r := testutil.ToFloat64(gv.gauge)
assert.Equal(t, float64(20), r)
}
func TestGaugeSet(t *testing.T) {
gaugeVec := NewGaugeVec(&GaugeVecOpts{
Namespace: "http_client",
Subsystem: "request",
Name: "duration_ms",
Help: "rpc server requests duration(ms).",
Labels: []string{"path"},
})
gaugeVec.close()
gv, _ := gaugeVec.(*promGuageVec)
gv.Set(666, "/users")
r := testutil.ToFloat64(gv.gauge)
assert.Equal(t, float64(666), r)
}

58
core/metric/histogram.go Normal file
View File

@@ -0,0 +1,58 @@
package metric
import (
"zero/core/proc"
prom "github.com/prometheus/client_golang/prometheus"
)
type (
HistogramVecOpts struct {
Namespace string
Subsystem string
Name string
Help string
Labels []string
Buckets []float64
}
HistogramVec interface {
Observe(v int64, lables ...string)
close() bool
}
promHistogramVec struct {
histogram *prom.HistogramVec
}
)
func NewHistogramVec(cfg *HistogramVecOpts) HistogramVec {
if cfg == nil {
return nil
}
vec := prom.NewHistogramVec(prom.HistogramOpts{
Namespace: cfg.Namespace,
Subsystem: cfg.Subsystem,
Name: cfg.Name,
Help: cfg.Help,
Buckets: cfg.Buckets,
}, cfg.Labels)
prom.MustRegister(vec)
hv := &promHistogramVec{
histogram: vec,
}
proc.AddShutdownListener(func() {
hv.close()
})
return hv
}
func (hv *promHistogramVec) Observe(v int64, labels ...string) {
hv.histogram.WithLabelValues(labels...).Observe(float64(v))
}
func (hv *promHistogramVec) close() bool {
return prom.Unregister(hv.histogram)
}

View File

@@ -0,0 +1,49 @@
package metric
import (
"strings"
"testing"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
)
func TestNewHistogramVec(t *testing.T) {
histogramVec := NewHistogramVec(&HistogramVecOpts{
Name: "duration_ms",
Help: "rpc server requests duration(ms).",
Buckets: []float64{1, 2, 3},
})
defer histogramVec.close()
histogramVecNil := NewHistogramVec(nil)
assert.NotNil(t, histogramVec)
assert.Nil(t, histogramVecNil)
}
func TestHistogramObserve(t *testing.T) {
histogramVec := NewHistogramVec(&HistogramVecOpts{
Name: "counts",
Help: "rpc server requests duration(ms).",
Buckets: []float64{1, 2, 3},
Labels: []string{"method"},
})
defer histogramVec.close()
hv, _ := histogramVec.(*promHistogramVec)
hv.Observe(2, "/Users")
metadata := `
# HELP counts rpc server requests duration(ms).
# TYPE counts histogram
`
val := `
counts_bucket{method="/Users",le="1"} 0
counts_bucket{method="/Users",le="2"} 1
counts_bucket{method="/Users",le="3"} 1
counts_bucket{method="/Users",le="+Inf"} 1
counts_sum{method="/Users"} 2
counts_count{method="/Users"} 1
`
err := testutil.CollectAndCompare(hv.histogram, strings.NewReader(metadata+val))
assert.Nil(t, err)
}

10
core/metric/metric.go Normal file
View File

@@ -0,0 +1,10 @@
package metric
// VectorOpts general configuration
type VectorOpts struct {
Namespace string
Subsystem string
Name string
Help string
Labels []string
}