diff options
author | Wolfy-J <[email protected]> | 2019-06-26 16:18:03 +0300 |
---|---|---|
committer | Wolfy-J <[email protected]> | 2019-06-26 16:18:03 +0300 |
commit | 73ce97e6fccfc59ab759787891d2cc2f8d3f88a5 (patch) | |
tree | be50996a5f24aa3b2d57bf70cdcbf4109d518554 | |
parent | 603239d5e39c5722e295c73eda552fe28f8378fd (diff) |
application specific metrics
-rw-r--r-- | service/metrics/config.go | 104 | ||||
-rw-r--r-- | service/metrics/service.go | 18 |
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()) + } } |