github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/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/juju/mgo/v3"
    10  	"github.com/prometheus/client_golang/prometheus"
    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 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  type stats struct {
    30  	Clusters     int
    31  	MasterConns  int
    32  	SlaveConns   int
    33  	SentOps      int
    34  	ReceivedOps  int
    35  	ReceivedDocs int
    36  	SocketsAlive int
    37  	SocketsInUse int
    38  	SocketRefs   int
    39  }
    40  
    41  // NewMgoStatsCollector returns a new MgoStatsCollector.
    42  func NewMgoStatsCollector(getCurrentStats func() mgo.Stats) *MgoStatsCollector {
    43  	// We need to track previous statistics so we can
    44  	// compute the delta for counter metrics.
    45  	var mu sync.Mutex
    46  	var prevStats stats
    47  	getStats := func() (current, previous stats) {
    48  		mu.Lock()
    49  		defer mu.Unlock()
    50  		previous = prevStats
    51  		currentStats := getCurrentStats()
    52  		current = stats{
    53  			Clusters:     currentStats.Clusters,
    54  			MasterConns:  currentStats.MasterConns,
    55  			SlaveConns:   currentStats.SlaveConns,
    56  			SentOps:      currentStats.SentOps,
    57  			ReceivedOps:  currentStats.ReceivedOps,
    58  			ReceivedDocs: currentStats.ReceivedDocs,
    59  			SocketsAlive: currentStats.SocketsAlive,
    60  			SocketsInUse: currentStats.SocketsInUse,
    61  			SocketRefs:   currentStats.SocketRefs,
    62  		}
    63  		prevStats = current
    64  		return current, previous
    65  	}
    66  
    67  	return &MgoStatsCollector{
    68  		getStats: getStats,
    69  
    70  		clustersGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    71  			Namespace: "mgo",
    72  			Name:      "clusters",
    73  			Help:      "Current number of clusters",
    74  		}),
    75  		masterConnsGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    76  			Namespace: "mgo",
    77  			Name:      "master_conns",
    78  			Help:      "Current number of master conns",
    79  		}),
    80  		slaveConnsGauge: prometheus.NewGauge(prometheus.GaugeOpts{
    81  			Namespace: "mgo",
    82  			Name:      "slave_conns",
    83  			Help:      "Current number of slave conns",
    84  		}),
    85  		sentOpsCounter: prometheus.NewCounter(prometheus.CounterOpts{
    86  			Namespace: "mgo",
    87  			Name:      "sent_ops_total",
    88  			Help:      "Total number of sent ops",
    89  		}),
    90  		receivedOpsCounter: prometheus.NewCounter(prometheus.CounterOpts{
    91  			Namespace: "mgo",
    92  			Name:      "received_ops_total",
    93  			Help:      "Total number of received ops",
    94  		}),
    95  		receivedDocsCounter: prometheus.NewCounter(prometheus.CounterOpts{
    96  			Namespace: "mgo",
    97  			Name:      "received_docs_total",
    98  			Help:      "Total number of received docs",
    99  		}),
   100  		socketsAliveGauge: prometheus.NewGauge(prometheus.GaugeOpts{
   101  			Namespace: "mgo",
   102  			Name:      "sockets_alive",
   103  			Help:      "Current number of sockets alive",
   104  		}),
   105  		socketsInuseGauge: prometheus.NewGauge(prometheus.GaugeOpts{
   106  			Namespace: "mgo",
   107  			Name:      "sockets_inuse",
   108  			Help:      "Current number of sockets in use",
   109  		}),
   110  		socketRefsGauge: prometheus.NewGauge(prometheus.GaugeOpts{
   111  			Namespace: "mgo",
   112  			Name:      "socket_refs",
   113  			Help:      "Current number of sockets referenced",
   114  		}),
   115  	}
   116  }
   117  
   118  // Describe is part of the prometheus.Collector interface.
   119  func (c *MgoStatsCollector) Describe(ch chan<- *prometheus.Desc) {
   120  	c.clustersGauge.Describe(ch)
   121  	c.masterConnsGauge.Describe(ch)
   122  	c.slaveConnsGauge.Describe(ch)
   123  	c.sentOpsCounter.Describe(ch)
   124  	c.receivedOpsCounter.Describe(ch)
   125  	c.receivedDocsCounter.Describe(ch)
   126  	c.socketsAliveGauge.Describe(ch)
   127  	c.socketsInuseGauge.Describe(ch)
   128  	c.socketRefsGauge.Describe(ch)
   129  }
   130  
   131  // Collect is part of the prometheus.Collector interface.
   132  func (c *MgoStatsCollector) Collect(ch chan<- prometheus.Metric) {
   133  	stats, prevStats := c.getStats()
   134  
   135  	c.clustersGauge.Set(float64(stats.Clusters))
   136  	c.masterConnsGauge.Set(float64(stats.MasterConns))
   137  	c.slaveConnsGauge.Set(float64(stats.SlaveConns))
   138  	if n := stats.SentOps - prevStats.SentOps; n > 0 {
   139  		c.sentOpsCounter.Add(float64(n))
   140  	}
   141  	if n := stats.ReceivedOps - prevStats.ReceivedOps; n > 0 {
   142  		c.receivedOpsCounter.Add(float64(n))
   143  	}
   144  	if n := stats.ReceivedDocs - prevStats.ReceivedDocs; n > 0 {
   145  		c.receivedDocsCounter.Add(float64(n))
   146  	}
   147  	c.socketsAliveGauge.Set(float64(stats.SocketsAlive))
   148  	c.socketsInuseGauge.Set(float64(stats.SocketsInUse))
   149  	c.socketRefsGauge.Set(float64(stats.SocketRefs))
   150  
   151  	c.clustersGauge.Collect(ch)
   152  	c.masterConnsGauge.Collect(ch)
   153  	c.slaveConnsGauge.Collect(ch)
   154  	c.sentOpsCounter.Collect(ch)
   155  	c.receivedOpsCounter.Collect(ch)
   156  	c.receivedDocsCounter.Collect(ch)
   157  	c.socketsAliveGauge.Collect(ch)
   158  	c.socketsInuseGauge.Collect(ch)
   159  	c.socketRefsGauge.Collect(ch)
   160  }