github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/peergrouper/metrics.go (about) 1 // Copyright 2019 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package peergrouper 5 6 import ( 7 "fmt" 8 "sync" 9 10 "github.com/juju/replicaset/v3" 11 "github.com/prometheus/client_golang/prometheus" 12 ) 13 14 const ( 15 metricsNamespace = "juju_peergrouper" 16 17 idLabel = "id" 18 addressLabel = "address" 19 stateLabel = "state" 20 ) 21 22 var ( 23 replicasetLabelNames = []string{ 24 idLabel, 25 addressLabel, 26 stateLabel, 27 } 28 ) 29 30 // Collector is a prometheus.Collector that collects metrics about 31 // the mongo replicaset status. 32 type Collector struct { 33 replicasetStatus *prometheus.GaugeVec 34 35 mu sync.Mutex 36 status []replicaset.MemberStatus 37 } 38 39 // NewMetricsCollector returns a new Collector. 40 func NewMetricsCollector() *Collector { 41 return &Collector{ 42 replicasetStatus: prometheus.NewGaugeVec( 43 prometheus.GaugeOpts{ 44 Namespace: metricsNamespace, 45 Name: "replicaset_status", 46 Help: "The details of the mongo replicaset.", 47 }, 48 replicasetLabelNames, 49 ), 50 } 51 } 52 53 // Describe is part of the prometheus.Collector interface. 54 func (c *Collector) Describe(ch chan<- *prometheus.Desc) { 55 c.replicasetStatus.Describe(ch) 56 } 57 58 // Collect is part of the prometheus.Collector interface. 59 func (c *Collector) Collect(ch chan<- prometheus.Metric) { 60 c.replicasetStatus.Reset() 61 62 c.mu.Lock() 63 for _, member := range c.status { 64 c.replicasetStatus.With(prometheus.Labels{ 65 idLabel: fmt.Sprint(member.Id), 66 addressLabel: member.Address, 67 stateLabel: member.State.String(), 68 }).Inc() 69 } 70 c.mu.Unlock() 71 72 c.replicasetStatus.Collect(ch) 73 } 74 75 func (c *Collector) update(statuses map[string]replicaset.MemberStatus) { 76 c.mu.Lock() 77 defer c.mu.Unlock() 78 79 c.status = make([]replicaset.MemberStatus, 0, len(statuses)) 80 for _, status := range statuses { 81 c.status = append(c.status, status) 82 } 83 } 84 85 func (c *Collector) report() map[string]interface{} { 86 c.mu.Lock() 87 defer c.mu.Unlock() 88 89 peers := make(map[string]interface{}) 90 for _, member := range c.status { 91 peers[fmt.Sprint(member.Id)] = map[string]interface{}{ 92 "address": member.Address, 93 "state": member.State.String(), 94 } 95 } 96 return map[string]interface{}{ 97 "replicaset": peers, 98 } 99 }