diff options
author | Valery Piashchynski <[email protected]> | 2020-02-10 17:12:11 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2020-02-10 17:12:11 +0300 |
commit | 04f8180bae119d0aa9be53db52165d3391a58efa (patch) | |
tree | c556ac35977a4bd2e80a4b28be46cca264ff96a3 /service | |
parent | 02be3eec1d8323a16031e86c1ddcc5c52c440176 (diff) |
Update go.mod/go.sum
New Register method
Diffstat (limited to 'service')
-rw-r--r-- | service/metrics/config.go | 8 | ||||
-rw-r--r-- | service/metrics/rpc.go | 97 | ||||
-rw-r--r-- | service/metrics/rpc_test.go | 52 |
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, |