summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2020-02-10 17:12:11 +0300
committerValery Piashchynski <[email protected]>2020-02-10 17:12:11 +0300
commit04f8180bae119d0aa9be53db52165d3391a58efa (patch)
treec556ac35977a4bd2e80a4b28be46cca264ff96a3 /service
parent02be3eec1d8323a16031e86c1ddcc5c52c440176 (diff)
Update go.mod/go.sum
New Register method
Diffstat (limited to 'service')
-rw-r--r--service/metrics/config.go8
-rw-r--r--service/metrics/rpc.go97
-rw-r--r--service/metrics/rpc_test.go52
3 files changed, 156 insertions, 1 deletions
diff --git a/service/metrics/config.go b/service/metrics/config.go
index c2f85201..341d0c70 100644
--- a/service/metrics/config.go
+++ b/service/metrics/config.go
@@ -15,6 +15,14 @@ type Config struct {
Collect map[string]Collector
}
+type NamedCollector struct {
+ // Name of the collector
+ Name string
+
+ // Collector structure
+ Collector
+}
+
// Collector describes single application specific metric.
type Collector struct {
// Namespace of the metric.
diff --git a/service/metrics/rpc.go b/service/metrics/rpc.go
index 9e7de640..285feee1 100644
--- a/service/metrics/rpc.go
+++ b/service/metrics/rpc.go
@@ -5,7 +5,9 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
-type rpcServer struct{ svc *Service }
+type rpcServer struct {
+ svc *Service
+}
// Metric represent single metric produced by the application.
type Metric struct {
@@ -57,6 +59,7 @@ func (rpc *rpcServer) Add(m *Metric, ok *bool) (err error) {
return fmt.Errorf("collector `%s` does not support method `Add`", m.Name)
}
+ // RPC, set ok to true as return value. Need by rpc.Call reply argument
*ok = true
return nil
}
@@ -88,6 +91,7 @@ func (rpc *rpcServer) Sub(m *Metric, ok *bool) (err error) {
return fmt.Errorf("collector `%s` does not support method `Sub`", m.Name)
}
+ // RPC, set ok to true as return value. Need by rpc.Call reply argument
*ok = true
return nil
}
@@ -126,6 +130,96 @@ func (rpc *rpcServer) Observe(m *Metric, ok *bool) (err error) {
return fmt.Errorf("collector `%s` does not support method `Observe`", m.Name)
}
+ // RPC, set ok to true as return value. Need by rpc.Call reply argument
+ *ok = true
+ return nil
+}
+// Register is used to register new collector in prometheus
+// THE TYPES ARE:
+// NamedCollector -> Collector with the name
+// bool -> RPC reply value
+// RETURNS:
+// error
+func (rpc *rpcServer) Register(c *NamedCollector, ok *bool) (err error) {
+ // MustRegister could panic, so, to return error and not shutdown whole app
+ // we recover and return error
+ defer func() {
+ if r, fail := recover().(error); fail {
+ err = r
+ }
+ }()
+
+ if rpc.svc.Collector(c.Name) != nil {
+ *ok = false
+ // alternative is to return error
+ // fmt.Errorf("tried to register existing collector with the name `%s`", c.Name)
+ return nil
+ }
+
+ var collector prometheus.Collector
+ switch c.Type {
+ case "histogram":
+ opts := prometheus.HistogramOpts{
+ Name: c.Name,
+ Namespace: c.Namespace,
+ Subsystem: c.Subsystem,
+ Help: c.Help,
+ Buckets: c.Buckets,
+ }
+
+ if len(c.Labels) != 0 {
+ collector = prometheus.NewHistogramVec(opts, c.Labels)
+ } else {
+ collector = prometheus.NewHistogram(opts)
+ }
+ case "gauge":
+ opts := prometheus.GaugeOpts{
+ Name: c.Name,
+ Namespace: c.Namespace,
+ Subsystem: c.Subsystem,
+ Help: c.Help,
+ }
+
+ if len(c.Labels) != 0 {
+ collector = prometheus.NewGaugeVec(opts, c.Labels)
+ } else {
+ collector = prometheus.NewGauge(opts)
+ }
+ case "counter":
+ opts := prometheus.CounterOpts{
+ Name: c.Name,
+ Namespace: c.Namespace,
+ Subsystem: c.Subsystem,
+ Help: c.Help,
+ }
+
+ if len(c.Labels) != 0 {
+ collector = prometheus.NewCounterVec(opts, c.Labels)
+ } else {
+ collector = prometheus.NewCounter(opts)
+ }
+ case "summary":
+ opts := prometheus.SummaryOpts{
+ Name: c.Name,
+ Namespace: c.Namespace,
+ Subsystem: c.Subsystem,
+ Help: c.Help,
+ }
+
+ if len(c.Labels) != 0 {
+ collector = prometheus.NewSummaryVec(opts, c.Labels)
+ } else {
+ collector = prometheus.NewSummary(opts)
+ }
+
+ default:
+ return fmt.Errorf("unknown collector type `%s`", c.Type)
+
+ }
+
+ // that method might panic, we handle it by recover
+ rpc.svc.MustRegister(collector)
+
*ok = true
return nil
}
@@ -158,6 +252,7 @@ func (rpc *rpcServer) Set(m *Metric, ok *bool) (err error) {
return fmt.Errorf("collector `%s` does not support method `Set`", m.Name)
}
+ // RPC, set ok to true as return value. Need by rpc.Call reply argument
*ok = true
return nil
}
diff --git a/service/metrics/rpc_test.go b/service/metrics/rpc_test.go
index 3fe48818..332f0f65 100644
--- a/service/metrics/rpc_test.go
+++ b/service/metrics/rpc_test.go
@@ -240,6 +240,58 @@ func Test_Sub_RPC_Vector(t *testing.T) {
assert.Contains(t, out, `user_gauge{section="first",type="core"} 90`)
}
+func Test_Register_RPC(t *testing.T) {
+ client, c := setup(
+ t,
+ `"user_gauge":{
+ "type": "gauge",
+ "labels": ["type", "section"]
+ }`,
+ "2319",
+ )
+ defer c.Stop()
+
+ var ok bool
+ assert.NoError(t, client.Call("metrics.Register", &NamedCollector{
+ Name: "custom_histogram",
+ Collector: Collector{
+ Namespace: "test_histogram",
+ Subsystem: "test_histogram",
+ Type: "histogram",
+ Help: "test_histogram",
+ Labels: nil,
+ Buckets: nil,
+ },
+ }, &ok))
+ assert.True(t, ok)
+
+ var ok2 bool
+ // histogram does not support Add, should be an error
+ assert.Error(t, client.Call("metrics.Add", Metric{
+ Name: "custom_histogram",
+ }, &ok2))
+ // ok should became false
+ assert.False(t, ok2)
+
+
+
+
+
+ // reset ok
+ //ok = false
+ //
+ //assert.NoError(t, client.Call("metrics.Sub", Metric{
+ // Name: "user_gauge",
+ // Value: 10.0,
+ // Labels: []string{"core", "first"},
+ //}, &ok))
+ //assert.True(t, ok)
+ //
+ //out, _, err := get("http://localhost:2119/metrics")
+ //assert.NoError(t, err)
+ //assert.Contains(t, out, `user_gauge{section="first",type="core"} 90`)
+}
+
func Test_Sub_RPC_CollectorError(t *testing.T) {
client, c := setup(
t,