summaryrefslogtreecommitdiff
path: root/service/metrics/service.go
diff options
context:
space:
mode:
Diffstat (limited to 'service/metrics/service.go')
-rw-r--r--service/metrics/service.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/service/metrics/service.go b/service/metrics/service.go
new file mode 100644
index 00000000..2c94568d
--- /dev/null
+++ b/service/metrics/service.go
@@ -0,0 +1,91 @@
+package metrics
+
+import (
+ "context"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+ "github.com/spiral/roadrunner/service/rpc"
+ "net/http"
+ "sync"
+)
+
+// ID declares public service name.
+const ID = "metrics"
+
+// Service to manage application metrics using Prometheus.
+type Service struct {
+ cfg *Config
+ mu sync.Mutex
+ http *http.Server
+ collectors sync.Map
+}
+
+// Init service.
+func (s *Service) Init(cfg *Config, r *rpc.Service) (bool, error) {
+ s.cfg = cfg
+
+ if r != nil {
+ if err := r.Register(ID, &rpcServer{s}); err != nil {
+ return false, err
+ }
+ }
+
+ return true, nil
+}
+
+// Enabled indicates that server is able to collect metrics.
+func (s *Service) Enabled() bool {
+ return s.cfg != nil
+}
+
+// Register new prometheus collector.
+func (s *Service) Register(c prometheus.Collector) error {
+ return prometheus.Register(c)
+}
+
+// MustRegister registers new collector or fails with panic.
+func (s *Service) MustRegister(c prometheus.Collector) {
+ if err := prometheus.Register(c); err != nil {
+ panic(err)
+ }
+}
+
+// Serve prometheus metrics service.
+func (s *Service) Serve() error {
+ // register application specific metrics
+ collectors, err := s.cfg.initCollectors()
+ if err != nil {
+ return err
+ }
+
+ for name, collector := range collectors {
+ s.collectors.Store(name, collector)
+ }
+
+ 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() {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ if s.http != nil {
+ // gracefully stop server
+ go s.http.Shutdown(context.Background())
+ }
+}
+
+// Collector returns application specific collector by name or nil if collector not found.
+func (s *Service) Collector(name string) prometheus.Collector {
+ collector, ok := s.collectors.Load(name)
+ if !ok {
+ return nil
+ }
+
+ return collector.(prometheus.Collector)
+}