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  }