github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/mongo/mongometrics/mgostatsmetrics.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package mongometrics
     5  
     6  import (
     7  	"sync"
     8  
     9  	"github.com/prometheus/client_golang/prometheus"
    10  	"gopkg.in/mgo.v2"
    11  )
    12  
    13  // MgoStatsCollector is a prometheus.Collector that collects metrics based
    14  // on mgo stats.
    15  type MgoStatsCollector struct {
    16  	getStats func() (current, previous mgo.Stats)
    17  
    18  	clustersGauge       prometheus.Gauge
    19  	masterConnsGauge    prometheus.Gauge
    20  	slaveConnsGauge     prometheus.Gauge
    21  	sentOpsCounter      prometheus.Counter
    22  	receivedOpsCounter  prometheus.Counter
    23  	receivedDocsCounter prometheus.Counter
    24  	socketsAliveGauge   prometheus.Gauge
    25  	socketsInuseGauge   prometheus.Gauge
    26  	socketRefsGauge     prometheus.Gauge
    27  }
    28  
    29  // NewMgoStatsCollector returns a new MgoStatsCollector.
    30  func NewMgoStatsCollector(getCurrentStats func() mgo.Stats) *MgoStatsCollector {
    31  	// We need to track previous statistics so we can
    32  	// compute the delta for counter metrics.
    33  	var mu sync.Mutex
    34  	var prevStats mgo.Stats
    35  	getStats := func() (current, previous mgo.Stats) {
    36  		mu.Lock()
    37  		defer mu.Unlock()
    38  		previous = prevStats
    39  		current = getCurrentStats()
    40  		prevStats = current
    41  		return current, previous
    42  	}
    43  
    44  	return &MgoStatsCollector{
    45  		getStats: getStats,
    46  
    47  		clustersGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    48  			Namespace: "mgo",
    49  			Name:      "clusters",
    50  			Help:      "Current number of clusters",
    51  		}),
    52  		masterConnsGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    53  			Namespace: "mgo",
    54  			Name:      "master_conns",
    55  			Help:      "Current number of master conns",
    56  		}),
    57  		slaveConnsGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    58  			Namespace: "mgo",
    59  			Name:      "slave_conns",
    60  			Help:      "Current number of slave conns",
    61  		}),
    62  		sentOpsCounter: prometheus.NewCounter(prometheus.CounterOpts{
    63  			Namespace: "mgo",
    64  			Name:      "sent_ops_total",
    65  			Help:      "Total number of sent ops",
    66  		}),
    67  		receivedOpsCounter: prometheus.NewCounter(prometheus.CounterOpts{
    68  			Namespace: "mgo",
    69  			Name:      "received_ops_total",
    70  			Help:      "Total number of received ops",
    71  		}),
    72  		receivedDocsCounter: prometheus.NewCounter(prometheus.CounterOpts{
    73  			Namespace: "mgo",
    74  			Name:      "received_docs_total",
    75  			Help:      "Total number of received docs",
    76  		}),
    77  		socketsAliveGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    78  			Namespace: "mgo",
    79  			Name:      "sockets_alive",
    80  			Help:      "Current number of sockets alive",
    81  		}),
    82  		socketsInuseGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    83  			Namespace: "mgo",
    84  			Name:      "sockets_inuse",
    85  			Help:      "Current number of sockets in use",
    86  		}),
    87  		socketRefsGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    88  			Namespace: "mgo",
    89  			Name:      "socket_refs",
    90  			Help:      "Current number of sockets referenced",
    91  		}),
    92  	}
    93  }
    94  
    95  // Describe is part of the prometheus.Collector interface.
    96  func (c *MgoStatsCollector) Describe(ch chan<- *prometheus.Desc) {
    97  	c.clustersGauge.Describe(ch)
    98  	c.masterConnsGauge.Describe(ch)
    99  	c.slaveConnsGauge.Describe(ch)
   100  	c.sentOpsCounter.Describe(ch)
   101  	c.receivedOpsCounter.Describe(ch)
   102  	c.receivedDocsCounter.Describe(ch)
   103  	c.socketsAliveGauge.Describe(ch)
   104  	c.socketsInuseGauge.Describe(ch)
   105  	c.socketRefsGauge.Describe(ch)
   106  }
   107  
   108  // Collect is part of the prometheus.Collector interface.
   109  func (c *MgoStatsCollector) Collect(ch chan<- prometheus.Metric) {
   110  	stats, prevStats := c.getStats()
   111  
   112  	c.clustersGauge.Set(float64(stats.Clusters))
   113  	c.masterConnsGauge.Set(float64(stats.MasterConns))
   114  	c.slaveConnsGauge.Set(float64(stats.SlaveConns))
   115  	if n := stats.SentOps - prevStats.SentOps; n > 0 {
   116  		c.sentOpsCounter.Add(float64(n))
   117  	}
   118  	if n := stats.ReceivedOps - prevStats.ReceivedOps; n > 0 {
   119  		c.receivedOpsCounter.Add(float64(n))
   120  	}
   121  	if n := stats.ReceivedDocs - prevStats.ReceivedDocs; n > 0 {
   122  		c.receivedDocsCounter.Add(float64(n))
   123  	}
   124  	c.socketsAliveGauge.Set(float64(stats.SocketsAlive))
   125  	c.socketsInuseGauge.Set(float64(stats.SocketsInUse))
   126  	c.socketRefsGauge.Set(float64(stats.SocketRefs))
   127  
   128  	c.clustersGauge.Collect(ch)
   129  	c.masterConnsGauge.Collect(ch)
   130  	c.slaveConnsGauge.Collect(ch)
   131  	c.sentOpsCounter.Collect(ch)
   132  	c.receivedOpsCounter.Collect(ch)
   133  	c.receivedDocsCounter.Collect(ch)
   134  	c.socketsAliveGauge.Collect(ch)
   135  	c.socketsInuseGauge.Collect(ch)
   136  	c.socketRefsGauge.Collect(ch)
   137  }