summaryrefslogtreecommitdiff
path: root/service/metrics
diff options
context:
space:
mode:
authorWolfy-J <[email protected]>2019-06-26 16:18:03 +0300
committerWolfy-J <[email protected]>2019-06-26 16:18:03 +0300
commit73ce97e6fccfc59ab759787891d2cc2f8d3f88a5 (patch)
treebe50996a5f24aa3b2d57bf70cdcbf4109d518554 /service/metrics
parent603239d5e39c5722e295c73eda552fe28f8378fd (diff)
application specific metrics
Diffstat (limited to 'service/metrics')
-rw-r--r--service/metrics/config.go104
-rw-r--r--service/metrics/service.go18
2 files changed, 114 insertions, 8 deletions
diff --git a/service/metrics/config.go b/service/metrics/config.go
index 799ba2d2..b93d8f50 100644
--- a/service/metrics/config.go
+++ b/service/metrics/config.go
@@ -1,23 +1,115 @@
package metrics
-import "github.com/spiral/roadrunner/service"
+import (
+ "fmt"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/spiral/roadrunner/service"
+)
type Config struct {
// Address to listen
Address string
- // Metrics define application specific metrics.
- Metrics map[string]Metric
+ // Collect define application specific metrics.
+ Collect map[string]Metric
}
// Metric describes single application specific metric.
type Metric struct {
- Type string
- Description string
- Labels []string
+ // Namespace of the metric.
+ Namespace string
+
+ // Subsystem of the metric.
+ Subsystem string
+
+ // Collector type (histogram, gauge, counter, summary).
+ Type string
+
+ // Help of collector.
+ Help string
+
+ // Labels for vectorized metrics.
+ Labels []string
+
+ // Buckets for histogram metric.
+ Buckets []float64
}
// Hydrate configuration.
func (c *Config) Hydrate(cfg service.Config) error {
return cfg.Unmarshal(c)
}
+
+// register application specific metrics.
+func (c *Config) registerMetrics() error {
+ if c.Collect == nil {
+ return nil
+ }
+
+ for name, m := range c.Collect {
+ var collector prometheus.Collector
+ switch m.Type {
+ case "histogram":
+ opts := prometheus.HistogramOpts{
+ Name: name,
+ Namespace: m.Namespace,
+ Subsystem: m.Subsystem,
+ Help: m.Help,
+ Buckets: m.Buckets,
+ }
+
+ if len(m.Labels) != 0 {
+ collector = prometheus.NewHistogramVec(opts, m.Labels)
+ } else {
+ collector = prometheus.NewHistogram(opts)
+ }
+ case "gauge":
+ opts := prometheus.GaugeOpts{
+ Name: name,
+ Namespace: m.Namespace,
+ Subsystem: m.Subsystem,
+ Help: m.Help,
+ }
+
+ if len(m.Labels) != 0 {
+ collector = prometheus.NewGaugeVec(opts, m.Labels)
+ } else {
+ collector = prometheus.NewGauge(opts)
+ }
+ case "counter":
+ opts := prometheus.CounterOpts{
+ Name: name,
+ Namespace: m.Namespace,
+ Subsystem: m.Subsystem,
+ Help: m.Help,
+ }
+
+ if len(m.Labels) != 0 {
+ collector = prometheus.NewCounterVec(opts, m.Labels)
+ } else {
+ collector = prometheus.NewCounter(opts)
+ }
+ case "summary":
+ opts := prometheus.SummaryOpts{
+ Name: name,
+ Namespace: m.Namespace,
+ Subsystem: m.Subsystem,
+ Help: m.Help,
+ }
+
+ if len(m.Labels) != 0 {
+ collector = prometheus.NewSummaryVec(opts, m.Labels)
+ } else {
+ collector = prometheus.NewSummary(opts)
+ }
+ default:
+ return fmt.Errorf("invalid metric type %s", m.Type)
+ }
+
+ if err := prometheus.Register(collector); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/service/metrics/service.go b/service/metrics/service.go
index 9d2a3dad..2823b1a4 100644
--- a/service/metrics/service.go
+++ b/service/metrics/service.go
@@ -5,6 +5,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
+ "sync"
)
// ID declares public service name.
@@ -13,6 +14,7 @@ const ID = "metrics"
// Service to manage application metrics using Prometheus.
type Service struct {
cfg *Config
+ mu sync.Mutex
http *http.Server
}
@@ -41,13 +43,25 @@ func (s *Service) MustRegister(c prometheus.Collector) {
// Serve prometheus metrics service.
func (s *Service) Serve() error {
+ // register application specific metrics
+ if err := s.cfg.registerMetrics(); err != nil {
+ return err
+ }
+
+ s.mu.Lock()
s.http = &http.Server{Addr: s.cfg.Address, Handler: promhttp.Handler()}
+ s.mu.Unlock()
return s.http.ListenAndServe()
}
// Stop prometheus metrics service.
func (s *Service) Stop() {
- // gracefully stop server
- go s.http.Shutdown(context.Background())
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ if s.http != nil {
+ // gracefully stop server
+ go s.http.Shutdown(context.Background())
+ }
}