github.com/puellanivis/breton@v0.2.16/lib/metrics/counter.go (about)

     1  package metrics
     2  
     3  import (
     4  	"github.com/prometheus/client_golang/prometheus"
     5  )
     6  
     7  // A CounterValue holds the tracking information for a specific Counter or a “Child” of a Counter.
     8  type CounterValue struct {
     9  	// we want to duplicate this every WithLabels() call,
    10  	// so we don’t use a pointer here.
    11  	metric
    12  
    13  	c  prometheus.Counter
    14  	cv *prometheus.CounterVec
    15  }
    16  
    17  // WithLabels provides access to a labeled dimension of the metric, and
    18  // returns a “Child” wherein the given labels are set.
    19  // The “Child” returned is cacheable by the Caller, so as to avoid having
    20  // to look it up again—this matters in latency-critical code.
    21  //
    22  // Caller MUST NOT attempt to set a label value that has been defined to be constant.
    23  func (c CounterValue) WithLabels(labels ...Labeler) *CounterValue {
    24  	// we are working with a new copy, so no mutex is necessary.
    25  	c.c = nil
    26  
    27  	c.labels = c.labels.With(labels...)
    28  
    29  	return &c
    30  }
    31  
    32  // Remove will remove a “Child” that matches the given labels from the metric, no longer exporting it.
    33  func (c *CounterValue) Remove(labels ...Labeler) bool {
    34  	if c.cv == nil {
    35  		return false
    36  	}
    37  
    38  	return c.cv.Delete(c.labels.getMap())
    39  }
    40  
    41  // Clear removes all “Children” from the metric.
    42  func (c *CounterValue) Clear() {
    43  	if c.cv != nil {
    44  		c.cv.Reset()
    45  	}
    46  }
    47  
    48  // Counter is a monotonically increasing value.
    49  func Counter(name string, help string, options ...Option) *CounterValue {
    50  	m := newMetric(name, help)
    51  
    52  	for _, opt := range options {
    53  		// in initialization, we throw the reverting function away
    54  		_ = opt(m)
    55  	}
    56  
    57  	c := &CounterValue{
    58  		metric: *m,
    59  	}
    60  
    61  	opts := prometheus.CounterOpts{
    62  		Name: name,
    63  		Help: help,
    64  	}
    65  
    66  	if c.labels != nil {
    67  		c.cv = prometheus.NewCounterVec(opts, c.labels.set.keys)
    68  		c.registry.MustRegister(c.cv)
    69  
    70  	} else {
    71  		c.c = prometheus.NewCounter(opts)
    72  		c.registry.MustRegister(c.c)
    73  	}
    74  
    75  	return c
    76  }
    77  
    78  // Inc increments the Counter by 1.
    79  func (c *CounterValue) Inc() {
    80  	if c.c == nil {
    81  		// function is idempotent, and won’t step on others’ toes
    82  		c.c = c.cv.With(c.labels.getMap())
    83  	}
    84  
    85  	c.c.Inc()
    86  }
    87  
    88  // Add increments the Counter by the given value.
    89  //
    90  // (Caller MUST NOT give a negative value.)
    91  func (c *CounterValue) Add(v float64) {
    92  	if v < 0 {
    93  		panic("counter cannot decrease in value")
    94  	}
    95  
    96  	if c.c == nil {
    97  		// function is idempotent, and won’t step on others’ toes
    98  		c.c = c.cv.With(c.labels.getMap())
    99  	}
   100  
   101  	c.c.Add(v)
   102  }