summaryrefslogtreecommitdiff
path: root/service/metrics
diff options
context:
space:
mode:
Diffstat (limited to 'service/metrics')
-rw-r--r--service/metrics/config.go27
-rw-r--r--service/metrics/rpc.go10
-rw-r--r--service/metrics/rpc_test.go168
3 files changed, 177 insertions, 28 deletions
diff --git a/service/metrics/config.go b/service/metrics/config.go
index 341d0c70..bee4f3d1 100644
--- a/service/metrics/config.go
+++ b/service/metrics/config.go
@@ -23,6 +23,23 @@ type NamedCollector struct {
Collector
}
+// CollectorType represents prometheus collector types
+type CollectorType string
+
+const (
+ // Histogram type
+ Histogram CollectorType = "histogram"
+
+ // Gauge type
+ Gauge CollectorType = "gauge"
+
+ // Counter type
+ Counter CollectorType = "counter"
+
+ // Summary type
+ Summary CollectorType = "summary"
+)
+
// Collector describes single application specific metric.
type Collector struct {
// Namespace of the metric.
@@ -32,7 +49,7 @@ type Collector struct {
Subsystem string
// Collector type (histogram, gauge, counter, summary).
- Type string
+ Type CollectorType
// Help of collector.
Help string
@@ -60,7 +77,7 @@ func (c *Config) getCollectors() (map[string]prometheus.Collector, error) {
for name, m := range c.Collect {
var collector prometheus.Collector
switch m.Type {
- case "histogram":
+ case Histogram:
opts := prometheus.HistogramOpts{
Name: name,
Namespace: m.Namespace,
@@ -74,7 +91,7 @@ func (c *Config) getCollectors() (map[string]prometheus.Collector, error) {
} else {
collector = prometheus.NewHistogram(opts)
}
- case "gauge":
+ case Gauge:
opts := prometheus.GaugeOpts{
Name: name,
Namespace: m.Namespace,
@@ -87,7 +104,7 @@ func (c *Config) getCollectors() (map[string]prometheus.Collector, error) {
} else {
collector = prometheus.NewGauge(opts)
}
- case "counter":
+ case Counter:
opts := prometheus.CounterOpts{
Name: name,
Namespace: m.Namespace,
@@ -100,7 +117,7 @@ func (c *Config) getCollectors() (map[string]prometheus.Collector, error) {
} else {
collector = prometheus.NewCounter(opts)
}
- case "summary":
+ case Summary:
opts := prometheus.SummaryOpts{
Name: name,
Namespace: m.Namespace,
diff --git a/service/metrics/rpc.go b/service/metrics/rpc.go
index 285feee1..9a36f14c 100644
--- a/service/metrics/rpc.go
+++ b/service/metrics/rpc.go
@@ -158,7 +158,7 @@ func (rpc *rpcServer) Register(c *NamedCollector, ok *bool) (err error) {
var collector prometheus.Collector
switch c.Type {
- case "histogram":
+ case Histogram:
opts := prometheus.HistogramOpts{
Name: c.Name,
Namespace: c.Namespace,
@@ -172,7 +172,7 @@ func (rpc *rpcServer) Register(c *NamedCollector, ok *bool) (err error) {
} else {
collector = prometheus.NewHistogram(opts)
}
- case "gauge":
+ case Gauge:
opts := prometheus.GaugeOpts{
Name: c.Name,
Namespace: c.Namespace,
@@ -185,7 +185,7 @@ func (rpc *rpcServer) Register(c *NamedCollector, ok *bool) (err error) {
} else {
collector = prometheus.NewGauge(opts)
}
- case "counter":
+ case Counter:
opts := prometheus.CounterOpts{
Name: c.Name,
Namespace: c.Namespace,
@@ -198,7 +198,7 @@ func (rpc *rpcServer) Register(c *NamedCollector, ok *bool) (err error) {
} else {
collector = prometheus.NewCounter(opts)
}
- case "summary":
+ case Summary:
opts := prometheus.SummaryOpts{
Name: c.Name,
Namespace: c.Namespace,
@@ -217,6 +217,8 @@ func (rpc *rpcServer) Register(c *NamedCollector, ok *bool) (err error) {
}
+ // add collector to sync.Map
+ rpc.svc.collectors.Store(c.Name, collector)
// that method might panic, we handle it by recover
rpc.svc.MustRegister(collector)
diff --git a/service/metrics/rpc_test.go b/service/metrics/rpc_test.go
index 332f0f65..3ef205c4 100644
--- a/service/metrics/rpc_test.go
+++ b/service/metrics/rpc_test.go
@@ -240,7 +240,7 @@ 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) {
+func Test_Register_RPC_Histogram(t *testing.T) {
client, c := setup(
t,
`"user_gauge":{
@@ -250,17 +250,17 @@ func Test_Register_RPC(t *testing.T) {
"2319",
)
defer c.Stop()
-
+
var ok bool
assert.NoError(t, client.Call("metrics.Register", &NamedCollector{
- Name: "custom_histogram",
+ Name: "custom_histogram",
Collector: Collector{
Namespace: "test_histogram",
Subsystem: "test_histogram",
- Type: "histogram",
+ Type: Histogram,
Help: "test_histogram",
Labels: nil,
- Buckets: nil,
+ Buckets: []float64{0.1, 0.2, 0.5},
},
}, &ok))
assert.True(t, ok)
@@ -268,28 +268,152 @@ func Test_Register_RPC(t *testing.T) {
var ok2 bool
// histogram does not support Add, should be an error
assert.Error(t, client.Call("metrics.Add", Metric{
- Name: "custom_histogram",
+ Name: "custom_histogram",
}, &ok2))
// ok should became false
assert.False(t, ok2)
+ out, _, err := get("http://localhost:2319/metrics")
+ assert.NoError(t, err)
+ assert.Contains(t, out, `TYPE test_histogram_test_histogram_custom_histogram histogram`)
+
+ // check buckets
+ assert.Contains(t, out, `test_histogram_test_histogram_custom_histogram_bucket{le="0.1"} 0`)
+ assert.Contains(t, out, `test_histogram_test_histogram_custom_histogram_bucket{le="0.2"} 0`)
+ assert.Contains(t, out, `test_histogram_test_histogram_custom_histogram_bucket{le="0.5"} 0`)
+}
+
+func Test_Register_RPC_Gauge(t *testing.T) {
+ // FOR register method, setup used just to init the rpc
+ client, c := setup(
+ t,
+ `"user_gauge":{
+ "type": "gauge",
+ "labels": ["type", "section"]
+ }`,
+ "2324",
+ )
+ defer c.Stop()
+
+ var ok bool
+ assert.NoError(t, client.Call("metrics.Register", &NamedCollector{
+ Name: "custom_gauge",
+ Collector: Collector{
+ Namespace: "test_gauge",
+ Subsystem: "test_gauge",
+ Type: Gauge,
+ Help: "test_gauge",
+ Labels: []string{"type", "section"},
+ Buckets: nil,
+ },
+ }, &ok))
+ assert.True(t, ok)
+
+ var ok2 bool
+ // Add to custom_gauge
+ assert.NoError(t, client.Call("metrics.Add", Metric{
+ Name: "custom_gauge",
+ Value: 100.0,
+ Labels: []string{"core", "first"},
+ }, &ok2))
+ // ok should became true
+ assert.True(t, ok2)
+
+ // Subtract from custom runtime metric
+ var ok3 bool
+ assert.NoError(t, client.Call("metrics.Sub", Metric{
+ Name: "custom_gauge",
+ Value: 10.0,
+ Labels: []string{"core", "first"},
+ }, &ok3))
+ assert.True(t, ok3)
+
+ out, _, err := get("http://localhost:2324/metrics")
+ assert.NoError(t, err)
+ assert.Contains(t, out, `test_gauge_test_gauge_custom_gauge{section="first",type="core"} 90`)
+}
+
+func Test_Register_RPC_Counter(t *testing.T) {
+ // FOR register method, setup used just to init the rpc
+ client, c := setup(
+ t,
+ `"user_gauge":{
+ "type": "gauge",
+ "labels": ["type", "section"]
+ }`,
+ "2328",
+ )
+ defer c.Stop()
+
+ var ok bool
+ assert.NoError(t, client.Call("metrics.Register", &NamedCollector{
+ Name: "custom_counter",
+ Collector: Collector{
+ Namespace: "test_counter",
+ Subsystem: "test_counter",
+ Type: Counter,
+ Help: "test_counter",
+ Labels: []string{"type", "section"},
+ Buckets: nil,
+ },
+ }, &ok))
+ assert.True(t, ok)
+ var ok2 bool
+ // Add to custom_counter
+ assert.NoError(t, client.Call("metrics.Add", Metric{
+ Name: "custom_counter",
+ Value: 100.0,
+ Labels: []string{"type2", "section2"},
+ }, &ok2))
+ // ok should became true
+ assert.True(t, ok2)
+ out, _, err := get("http://localhost:2328/metrics")
+ assert.NoError(t, err)
+ assert.Contains(t, out, `test_counter_test_counter_custom_counter{section="section2",type="type2"} 100`)
+}
+func Test_Register_RPC_Summary(t *testing.T) {
+ // FOR register method, setup used just to init the rpc
+ client, c := setup(
+ t,
+ `"user_gauge":{
+ "type": "gauge",
+ "labels": ["type", "section"]
+ }`,
+ "6666",
+ )
+ defer c.Stop()
- // 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`)
+ var ok bool
+ assert.NoError(t, client.Call("metrics.Register", &NamedCollector{
+ Name: "custom_summary",
+ Collector: Collector{
+ Namespace: "test_summary",
+ Subsystem: "test_summary",
+ Type: Summary,
+ Help: "test_summary",
+ Labels: nil,
+ Buckets: nil,
+ },
+ }, &ok))
+ assert.True(t, ok)
+
+ var ok2 bool
+ // Add to custom_summary is not supported
+ assert.Error(t, client.Call("metrics.Add", Metric{
+ Name: "custom_summary",
+ Value: 100.0,
+ Labels: []string{"type22", "section22"},
+ }, &ok2))
+ // ok should became false
+ assert.False(t, ok2)
+
+ out, _, err := get("http://localhost:6666/metrics")
+ assert.NoError(t, err)
+ assert.Contains(t, out, `test_summary_test_summary_custom_summary_sum 0`)
+ assert.Contains(t, out, `test_summary_test_summary_custom_summary_count 0`)
}
func Test_Sub_RPC_CollectorError(t *testing.T) {
@@ -673,6 +797,8 @@ func Test_Add_RPC_CollectorError(t *testing.T) {
Value: 100.0,
Labels: []string{"missing"},
}, &ok))
+
+ assert.False(t, ok)
}
func Test_Add_RPC_MetricError(t *testing.T) {
@@ -692,6 +818,8 @@ func Test_Add_RPC_MetricError(t *testing.T) {
Value: 100.0,
Labels: []string{"missing"},
}, &ok))
+
+ assert.False(t, ok)
}
func Test_Add_RPC_MetricError_2(t *testing.T) {
@@ -710,6 +838,8 @@ func Test_Add_RPC_MetricError_2(t *testing.T) {
Name: "user_gauge",
Value: 100.0,
}, &ok))
+
+ assert.False(t, ok)
}
func Test_Add_RPC_MetricError_3(t *testing.T) {