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 }